diff --git a/content/docs/references/ai/agent.mdx b/content/docs/references/ai/agent.mdx index b29d73317a..13f06435fa 100644 --- a/content/docs/references/ai/agent.mdx +++ b/content/docs/references/ai/agent.mdx @@ -29,7 +29,8 @@ const result = AIKnowledge.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | -| **topics** | `string[]` | ✅ | Topics/Tags to recruit knowledge from | +| **sources** | `string[]` | optional | Knowledge sources/tags to recruit RAG context from. Canonical key consumed by the agent renderer (objectui AgentPreview KnowledgeSummary). | +| **topics** | `string[]` | optional | Deprecated alias for `sources` (spec key ≠ consumed key drift, liveness audit #1878/#1891). Prefer `sources`; `topics` is retained for back-compat but the renderer reads `sources`. | | **indexes** | `string[]` | ✅ | Vector Store Indexes | @@ -79,7 +80,7 @@ const result = AIKnowledge.parse(data); | **surface** | `Enum<'ask' \| 'build'>` | ✅ | Product surface this agent binds ('ask' \| 'build') — ADR-0063 §1 | | **skills** | `string[]` | optional | Skill names to attach (Agent→Skill→Tool architecture) | | **tools** | `{ type: Enum<'action' \| 'flow' \| 'query' \| 'vector_search'>; name: string; description?: string }[]` | optional | Direct tool references (legacy fallback) | -| **knowledge** | `{ topics: string[]; indexes: string[] }` | optional | RAG access | +| **knowledge** | `{ sources?: string[]; topics?: string[]; indexes: string[] }` | optional | RAG access | | **active** | `boolean` | ✅ | | | **access** | `string[]` | optional | Who can chat with this agent | | **permissions** | `string[]` | optional | Required permission-set capabilities | diff --git a/content/docs/references/ai/tool.mdx b/content/docs/references/ai/tool.mdx index 8397d3578e..c7ca0e36c4 100644 --- a/content/docs/references/ai/tool.mdx +++ b/content/docs/references/ai/tool.mdx @@ -27,6 +27,8 @@ const result = Tool.parse(data); ## Tool +AI tool definition. [READ-ONLY PROJECTION — not an execution entry point] Authoring a tool as metadata does NOT make it runnable: this schema has no `implementation`/`handler` field and no framework executor loads a metadata-authored tool. The runtime executes a separately-registered `AIToolDefinition` (cloud `@objectstack/service-ai`); tool metadata is a one-way projection for Studio/discovery. Do not expect a hand-authored tool to run in the open edition (liveness audit #1878/#1892). + ### Properties | Property | Type | Required | Description | diff --git a/content/docs/references/automation/webhook.mdx b/content/docs/references/automation/webhook.mdx index 1a1e8a2b8d..1f0a5fe244 100644 --- a/content/docs/references/automation/webhook.mdx +++ b/content/docs/references/automation/webhook.mdx @@ -71,7 +71,7 @@ const result = Webhook.parse(data); | **body** | `any` | optional | Request body payload (if not using default record data) | | **payloadFields** | `string[]` | optional | Fields to include. Empty = All | | **includeSession** | `boolean` | ✅ | Include user session info | -| **authentication** | `{ type: Enum<'none' \| 'bearer' \| 'basic' \| 'api-key'>; credentials?: Record }` | optional | Authentication configuration | +| **authentication** | `{ type: Enum<'none' \| 'bearer' \| 'basic' \| 'api-key'>; credentials?: Record }` | optional | Authentication configuration. [EXPERIMENTAL — not enforced] The webhook delivery path only applies HMAC signing via `secret`; bearer/basic/api-key credentials are not attached to outbound requests yet (liveness audit #1878/#1893). | | **retryPolicy** | `{ maxRetries: integer; backoffStrategy: Enum<'exponential' \| 'linear' \| 'fixed'>; initialDelayMs: integer; maxDelayMs: integer }` | optional | Retry policy configuration | | **timeoutMs** | `integer` | ✅ | Request timeout in milliseconds | | **secret** | `string` | optional | Signing secret for HMAC signature verification | diff --git a/content/docs/references/integration/connector.mdx b/content/docs/references/integration/connector.mdx index d7decca213..3275f4847e 100644 --- a/content/docs/references/integration/connector.mdx +++ b/content/docs/references/integration/connector.mdx @@ -473,7 +473,7 @@ Synchronization strategy | **body** | `any` | optional | Request body payload (if not using default record data) | | **payloadFields** | `string[]` | optional | Fields to include. Empty = All | | **includeSession** | `boolean` | ✅ | Include user session info | -| **authentication** | `{ type: Enum<'none' \| 'bearer' \| 'basic' \| 'api-key'>; credentials?: Record }` | optional | Authentication configuration | +| **authentication** | `{ type: Enum<'none' \| 'bearer' \| 'basic' \| 'api-key'>; credentials?: Record }` | optional | Authentication configuration. [EXPERIMENTAL — not enforced] The webhook delivery path only applies HMAC signing via `secret`; bearer/basic/api-key credentials are not attached to outbound requests yet (liveness audit #1878/#1893). | | **retryPolicy** | `{ maxRetries: integer; backoffStrategy: Enum<'exponential' \| 'linear' \| 'fixed'>; initialDelayMs: integer; maxDelayMs: integer }` | optional | Retry policy configuration | | **timeoutMs** | `integer` | ✅ | Request timeout in milliseconds | | **secret** | `string` | optional | Signing secret for HMAC signature verification | diff --git a/content/docs/references/kernel/manifest.mdx b/content/docs/references/kernel/manifest.mdx index 6bbc9257f2..a06b9b5c95 100644 --- a/content/docs/references/kernel/manifest.mdx +++ b/content/docs/references/kernel/manifest.mdx @@ -64,7 +64,7 @@ const result = Manifest.parse(data); | **data** | `{ object: string; externalId?: string; mode?: Enum<'insert' \| 'update' \| 'upsert' \| 'replace' \| 'ignore'>; env?: Enum<'prod' \| 'dev' \| 'test'>[]; … }[]` | optional | Initial seed data (prefer top-level data field) | | **capabilities** | `{ implements?: { protocol: object; conformance?: Enum<'full' \| 'partial' \| 'experimental' \| 'deprecated'>; implementedFeatures?: string[]; features?: { name: string; enabled?: boolean; description?: string; sinceVersion?: string; … }[]; … }[]; provides?: { id: string; name: string; description?: string; version: object; … }[]; requires?: { pluginId: string; version: string; optional?: boolean; reason?: string; … }[]; extensionPoints?: { id: string; name: string; description?: string; type: Enum<'action' \| 'hook' \| 'widget' \| 'provider' \| 'transformer' \| 'validator' \| 'decorator'>; … }[]; … }` | optional | Plugin capability declarations for interoperability | | **extensions** | `Record` | optional | Extension points and contributions | -| **navigationContributions** | `{ app: string; group?: string; priority?: integer; items: { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … }[] }[]` | optional | Navigation items this package contributes into apps owned by other packages | +| **navigationContributions** | `{ app: string; group?: string; priority?: integer; items: { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { type: 'separator'; id?: string; order?: number } \| { id: string; label: string; icon?: string; order?: number; … }[] }[]` | optional | Navigation items this package contributes into apps owned by other packages | | **loading** | `{ strategy?: Enum<'eager' \| 'lazy' \| 'parallel' \| 'deferred' \| 'on-demand'>; preload?: object; codeSplitting?: object; dynamicImport?: object; … }` | optional | Plugin loading and runtime behavior configuration | | **engine** | `{ objectstack: string }` | optional | Platform compatibility requirements (legacy; superseded by `engines`) | | **engines** | `{ platform?: string; protocol?: string }` | optional | Plugin compatibility ranges (ADR-0025 §3.2; supersedes `engine`) | diff --git a/content/docs/references/system/job.mdx b/content/docs/references/system/job.mdx index 9b04b25d11..126044fab7 100644 --- a/content/docs/references/system/job.mdx +++ b/content/docs/references/system/job.mdx @@ -62,8 +62,8 @@ const result = CronSchedule.parse(data); | **description** | `string` | optional | Job description / purpose | | **schedule** | `{ type: 'cron'; expression: string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; timezone?: string } \| { type: 'interval'; intervalMs: integer } \| { type: 'once'; at: string }` | ✅ | Job schedule configuration | | **handler** | `string` | ✅ | Handler function name (must match a key in `defineStack({ functions })`) | -| **retryPolicy** | `{ maxRetries?: integer; backoffMs?: integer; backoffMultiplier?: number }` | optional | Retry policy configuration | -| **timeout** | `integer` | optional | Timeout in milliseconds | +| **retryPolicy** | `{ maxRetries?: integer; backoffMs?: integer; backoffMultiplier?: number }` | optional | Retry policy configuration. [EXPERIMENTAL — not enforced] The service-job scheduler does not yet read retryPolicy; failed runs are not retried per this config (liveness audit #1878/#1893). | +| **timeout** | `integer` | optional | Timeout in milliseconds. [EXPERIMENTAL — not enforced] The service-job scheduler does not yet enforce a per-run timeout (liveness audit #1878/#1893). | | **enabled** | `boolean` | optional | Whether the job is enabled | diff --git a/content/docs/references/system/translation.mdx b/content/docs/references/system/translation.mdx index 6d310fe869..8709737b62 100644 --- a/content/docs/references/system/translation.mdx +++ b/content/docs/references/system/translation.mdx @@ -154,9 +154,9 @@ Internationalization configuration | **supportedLocales** | `string[]` | ✅ | Supported BCP-47 locale codes | | **fallbackLocale** | `string` | optional | Fallback locale code | | **fileOrganization** | `Enum<'bundled' \| 'per_locale' \| 'per_namespace'>` | ✅ | File organization strategy | -| **messageFormat** | `Enum<'icu' \| 'simple'>` | ✅ | Message interpolation format (ICU MessageFormat or simple) | +| **messageFormat** | `Enum<'icu' \| 'simple'>` | ✅ | Message interpolation format (ICU MessageFormat or simple). [EXPERIMENTAL — 'icu' not enforced] No ICU MessageFormat engine is wired; messageFormat:'icu' is accepted but interpolation falls back to simple substitution (liveness audit #1878/#1893). | | **lazyLoad** | `boolean` | ✅ | Load translations on demand | -| **cache** | `boolean` | ✅ | Cache loaded translations | +| **cache** | `boolean` | ✅ | Cache loaded translations. [EXPERIMENTAL — not enforced] No runtime consumer reads this cache flag yet (liveness audit #1878/#1893). | --- diff --git a/content/docs/references/ui/app.mdx b/content/docs/references/ui/app.mdx index 1b54fa315a..4a682f552f 100644 --- a/content/docs/references/ui/app.mdx +++ b/content/docs/references/ui/app.mdx @@ -54,6 +54,7 @@ const result = ActionNavItem.parse(data); | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -75,11 +76,11 @@ const result = ActionNavItem.parse(data); | **version** | `string` | optional | App version | | **description** | `string` | optional | App description | | **icon** | `string` | optional | App icon used in the App Launcher | -| **branding** | `{ primaryColor?: string; logo?: string; favicon?: string }` | optional | App-specific branding | +| **branding** | `{ primaryColor?: string; accentColor?: string; logo?: string; favicon?: string }` | optional | App-specific branding | | **active** | `boolean` | optional | Whether the app is enabled | | **isDefault** | `boolean` | optional | Is default app | | **hidden** | `boolean` | optional | Hide from the App Switcher; the shell surfaces hidden apps via the avatar menu instead | -| **navigation** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … }[]` | optional | Full navigation tree for the app sidebar | +| **navigation** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { type: 'separator'; id?: string; order?: number } \| { id: string; label: string; icon?: string; order?: number; … }[]` | optional | Full navigation tree for the app sidebar | | **areas** | `{ id: string; label: string; icon?: string; order?: number; … }[]` | optional | Navigation areas for partitioning navigation by business domain | | **contextSelectors** | `{ id: string; label: string; icon?: string; optionsSource: object; … }[]` | optional | App-level scope dropdowns whose value is injected into nav items as `{}` template vars | | **homePageId** | `string` | optional | ID of the navigation item to serve as landing page | @@ -110,6 +111,7 @@ const result = ActionNavItem.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **primaryColor** | `string` | optional | Primary theme color hex code | +| **accentColor** | `string` | optional | Accent color hex code (highlights, active states). Declared to match the objectui ConsoleLayout read of branding.accentColor (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **logo** | `string` | optional | Custom logo URL for this app | | **favicon** | `string` | optional | Custom favicon URL for this app | @@ -145,6 +147,7 @@ const result = ActionNavItem.parse(data); | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -167,6 +170,7 @@ const result = ActionNavItem.parse(data); | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -188,6 +192,7 @@ const result = ActionNavItem.parse(data); | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -211,7 +216,7 @@ const result = ActionNavItem.parse(data); | **description** | `string` | optional | Area description | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL) for this area. | | **requiredPermissions** | `string[]` | optional | Permissions required to access this area | -| **navigation** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … }[]` | ✅ | Navigation items within this area | +| **navigation** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { type: 'separator'; id?: string; order?: number } \| { id: string; label: string; icon?: string; order?: number; … }[]` | ✅ | Navigation items within this area | --- @@ -227,7 +232,7 @@ A navigation contribution: a package injecting nav items into an app it does not | **app** | `string` | ✅ | Target app name to contribute navigation into (e.g. "setup") | | **group** | `string` | optional | Target group nav-item id to append into (e.g. "group_integrations"); omit to append at the app top level | | **priority** | `integer` | optional | Merge priority within the target group — lower applied first (matches object extender priority) | -| **items** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … }[]` | ✅ | Navigation items contributed into the target app/group | +| **items** | `{ id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { id: string; label: string; icon?: string; order?: number; … } \| { type: 'separator'; id?: string; order?: number } \| { id: string; label: string; icon?: string; order?: number; … }[]` | ✅ | Navigation items contributed into the target app/group | --- @@ -251,6 +256,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -278,6 +284,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -300,6 +307,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -323,6 +331,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -346,6 +355,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -368,6 +378,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -390,6 +401,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -402,6 +414,20 @@ This schema accepts one of the following structures: #### Option 8 +**Type:** `separator` + +### Properties + +| Property | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **type** | `'separator'` | ✅ | | +| **id** | `string` | optional | Optional id for the separator | +| **order** | `number` | optional | Sort order within the same level (lower = first) | + +--- + +#### Option 9 + **Type:** `group` ### Properties @@ -413,6 +439,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -437,6 +464,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -462,6 +490,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -484,6 +513,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | @@ -505,6 +535,7 @@ This schema accepts one of the following structures: | **icon** | `string` | optional | Icon name | | **order** | `number` | optional | Sort order within the same level (lower = first) | | **badge** | `string \| number` | optional | Badge text or count displayed on the item | +| **badgeVariant** | `Enum<'default' \| 'secondary' \| 'destructive' \| 'outline'>` | optional | Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894). | | **visible** | `string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }` | optional | Visibility predicate (CEL). e.g. P`'org_admin' in current_user.positions` | | **requiredPermissions** | `string[]` | optional | Permissions required to access this item | | **requiresObject** | `string` | optional | Hide/disable this entry unless the named object is registered in the runtime | diff --git a/content/docs/references/ui/portal.mdx b/content/docs/references/ui/portal.mdx index 85b7da66ee..5cca677724 100644 --- a/content/docs/references/ui/portal.mdx +++ b/content/docs/references/ui/portal.mdx @@ -85,6 +85,8 @@ const result = Portal.parse(data); ## Portal +Portal projection. [EXPERIMENTAL — not enforced] PortalSchema is not registered as an authorable metadata type; no dispatcher route family, auth scope, LayoutDispatcher, NavigationBuilder or ThemeProvider consumes it yet. The entire schema is a forward-looking design (framework #1294); authoring a portal today is a no-op (liveness audit #1878/#1893). + ### Properties | Property | Type | Required | Description | diff --git a/content/docs/references/ui/theme.mdx b/content/docs/references/ui/theme.mdx index 31041c2df6..9104025b11 100644 --- a/content/docs/references/ui/theme.mdx +++ b/content/docs/references/ui/theme.mdx @@ -162,19 +162,19 @@ const result = Animation.parse(data); | **mode** | `Enum<'light' \| 'dark' \| 'auto'>` | ✅ | Theme mode (light, dark, or auto) | | **colors** | `{ primary: string; secondary?: string; accent?: string; success?: string; … }` | ✅ | Color palette configuration | | **typography** | `{ fontFamily?: object; fontSize?: object; fontWeight?: object; lineHeight?: object; … }` | optional | Typography settings | -| **spacing** | `{ 0?: string; 1?: string; 2?: string; 3?: string; … }` | optional | Spacing scale | +| **spacing** | `{ 0?: string; 1?: string; 2?: string; 3?: string; … }` | optional | Spacing scale. [EXPERIMENTAL — not enforced] generateThemeVars does not emit spacing tokens yet (liveness audit #1878/#1893). | | **borderRadius** | `{ none?: string; sm?: string; base?: string; md?: string; … }` | optional | Border radius scale | | **shadows** | `{ none?: string; sm?: string; base?: string; md?: string; … }` | optional | Box shadow effects | -| **breakpoints** | `{ xs?: string; sm?: string; md?: string; lg?: string; … }` | optional | Responsive breakpoints | +| **breakpoints** | `{ xs?: string; sm?: string; md?: string; lg?: string; … }` | optional | Responsive breakpoints. [EXPERIMENTAL — not enforced] generateThemeVars does not emit breakpoint tokens yet (liveness audit #1878/#1893). | | **animation** | `{ duration?: object; timing?: object }` | optional | Animation settings | | **zIndex** | `{ base?: number; dropdown?: number; sticky?: number; fixed?: number; … }` | optional | Z-index scale for layering | | **customVars** | `Record` | optional | Custom CSS variables (key-value pairs) | | **logo** | `{ light?: string; dark?: string; favicon?: string }` | optional | Logo assets | | **extends** | `string` | optional | Base theme to extend from | -| **density** | `Enum<'compact' \| 'regular' \| 'spacious'>` | optional | Display density: compact, regular, or spacious | +| **density** | `Enum<'compact' \| 'regular' \| 'spacious'>` | optional | Display density: compact, regular, or spacious. [EXPERIMENTAL — not enforced] The theme engine does not consume theme-level density yet; view-level densityMode is a separate live setting (liveness audit #1878/#1893). | | **wcagContrast** | `Enum<'AA' \| 'AAA'>` | optional | WCAG color contrast level (AA or AAA) | -| **rtl** | `boolean` | optional | Enable right-to-left layout direction | -| **touchTarget** | `{ minWidth: number; minHeight: number; padding?: number; hitSlop?: object }` | optional | Touch target sizing defaults | +| **rtl** | `boolean` | optional | Enable right-to-left layout direction. [EXPERIMENTAL — not enforced] No renderer reads theme.rtl yet (liveness audit #1878/#1893). | +| **touchTarget** | `{ minWidth: number; minHeight: number; padding?: number; hitSlop?: object }` | optional | Touch target sizing defaults. [EXPERIMENTAL — not enforced] No renderer consumes touchTarget yet (liveness audit #1878/#1893). | | **keyboardNavigation** | `{ tabOrder: Enum<'auto' \| 'manual'>; skipLinks: boolean; focusVisible: boolean; focusTrap?: object; … }` | optional | Keyboard focus management settings | diff --git a/packages/spec/liveness/object.json b/packages/spec/liveness/object.json index 1e9a020b91..a5a0258f52 100644 --- a/packages/spec/liveness/object.json +++ b/packages/spec/liveness/object.json @@ -179,11 +179,13 @@ }, "trash": { "status": "dead", - "evidence": "no behavior-changing reader" + "evidence": "no behavior-changing reader", + "note": "Kept `dead` (not experimental): enable.trash defaults to true, and the author-side liveness lint auto-warns on experimental props — for a default-true boolean it cannot distinguish an authored value from the schema default, so tagging it experimental would warn on every object (noise). Disposition for #1893 is prune-or-build, tracked in the sub-issue; no authorWarn so it stays silent." }, "mru": { "status": "dead", - "evidence": "no behavior-changing reader" + "evidence": "no behavior-changing reader", + "note": "Kept `dead` (not experimental) for the same default-true-boolean reason as enable.trash; disposition tracked in #1893. No authorWarn so it stays silent." }, "clone": { "status": "live", diff --git a/packages/spec/src/ai/agent.zod.ts b/packages/spec/src/ai/agent.zod.ts index 6494974562..0e3ec8e8ed 100644 --- a/packages/spec/src/ai/agent.zod.ts +++ b/packages/spec/src/ai/agent.zod.ts @@ -32,7 +32,8 @@ export const AIToolSchema = lazySchema(() => z.object({ * RAG configuration. */ export const AIKnowledgeSchema = lazySchema(() => z.object({ - topics: z.array(z.string()).describe('Topics/Tags to recruit knowledge from'), + sources: z.array(z.string()).optional().describe('Knowledge sources/tags to recruit RAG context from. Canonical key consumed by the agent renderer (objectui AgentPreview KnowledgeSummary).'), + topics: z.array(z.string()).optional().describe('Deprecated alias for `sources` (spec key ≠ consumed key drift, liveness audit #1878/#1891). Prefer `sources`; `topics` is retained for back-compat but the renderer reads `sources`.'), indexes: z.array(z.string()).describe('Vector Store Indexes'), })); diff --git a/packages/spec/src/ai/tool.zod.ts b/packages/spec/src/ai/tool.zod.ts index adf58e5349..72c8494d9d 100644 --- a/packages/spec/src/ai/tool.zod.ts +++ b/packages/spec/src/ai/tool.zod.ts @@ -117,7 +117,7 @@ export const ToolSchema = lazySchema(() => z.object({ // ADR-0010 — runtime protection envelope (internal — set by loader). ...MetadataProtectionFields, -})); +}).describe('AI tool definition. [READ-ONLY PROJECTION — not an execution entry point] Authoring a tool as metadata does NOT make it runnable: this schema has no `implementation`/`handler` field and no framework executor loads a metadata-authored tool. The runtime executes a separately-registered `AIToolDefinition` (cloud `@objectstack/service-ai`); tool metadata is a one-way projection for Studio/discovery. Do not expect a hand-authored tool to run in the open edition (liveness audit #1878/#1892).')); export type Tool = z.infer; diff --git a/packages/spec/src/automation/webhook.zod.ts b/packages/spec/src/automation/webhook.zod.ts index bccfecf21b..d25d1b0353 100644 --- a/packages/spec/src/automation/webhook.zod.ts +++ b/packages/spec/src/automation/webhook.zod.ts @@ -99,7 +99,7 @@ export const WebhookSchema = lazySchema(() => z.object({ authentication: z.object({ type: z.enum(['none', 'bearer', 'basic', 'api-key']).describe('Authentication type'), credentials: z.record(z.string(), z.string()).optional().describe('Authentication credentials'), - }).optional().describe('Authentication configuration'), + }).optional().describe("Authentication configuration. [EXPERIMENTAL — not enforced] The webhook delivery path only applies HMAC signing via `secret`; bearer/basic/api-key credentials are not attached to outbound requests yet (liveness audit #1878/#1893)."), /** Retry Policy */ retryPolicy: z.object({ diff --git a/packages/spec/src/system/job.zod.ts b/packages/spec/src/system/job.zod.ts index 52053b745d..6ff4912410 100644 --- a/packages/spec/src/system/job.zod.ts +++ b/packages/spec/src/system/job.zod.ts @@ -87,8 +87,8 @@ export const JobSchema = lazySchema(() => z.object({ description: z.string().optional().describe('Job description / purpose'), schedule: ScheduleSchema.describe('Job schedule configuration'), handler: z.string().describe('Handler function name (must match a key in `defineStack({ functions })`)'), - retryPolicy: RetryPolicySchema.optional().describe('Retry policy configuration'), - timeout: z.number().int().positive().optional().describe('Timeout in milliseconds'), + retryPolicy: RetryPolicySchema.optional().describe('Retry policy configuration. [EXPERIMENTAL — not enforced] The service-job scheduler does not yet read retryPolicy; failed runs are not retried per this config (liveness audit #1878/#1893).'), + timeout: z.number().int().positive().optional().describe('Timeout in milliseconds. [EXPERIMENTAL — not enforced] The service-job scheduler does not yet enforce a per-run timeout (liveness audit #1878/#1893).'), enabled: z.boolean().default(true).describe('Whether the job is enabled'), })); diff --git a/packages/spec/src/system/translation.zod.ts b/packages/spec/src/system/translation.zod.ts index 80e5126623..a68944a59b 100644 --- a/packages/spec/src/system/translation.zod.ts +++ b/packages/spec/src/system/translation.zod.ts @@ -414,11 +414,11 @@ export const TranslationConfigSchema = lazySchema(() => z.object({ * @default 'simple' */ messageFormat: MessageFormatSchema.default('simple') - .describe('Message interpolation format (ICU MessageFormat or simple)'), + .describe("Message interpolation format (ICU MessageFormat or simple). [EXPERIMENTAL — 'icu' not enforced] No ICU MessageFormat engine is wired; messageFormat:'icu' is accepted but interpolation falls back to simple substitution (liveness audit #1878/#1893)."), /** Load translations on demand instead of eagerly */ lazyLoad: z.boolean().default(false).describe('Load translations on demand'), /** Cache loaded translations in memory */ - cache: z.boolean().default(true).describe('Cache loaded translations'), + cache: z.boolean().default(true).describe('Cache loaded translations. [EXPERIMENTAL — not enforced] No runtime consumer reads this cache flag yet (liveness audit #1878/#1893).'), }).describe('Internationalization configuration')); export type TranslationConfig = z.infer; diff --git a/packages/spec/src/ui/app.zod.ts b/packages/spec/src/ui/app.zod.ts index 0d46399492..dbe2313f55 100644 --- a/packages/spec/src/ui/app.zod.ts +++ b/packages/spec/src/ui/app.zod.ts @@ -41,6 +41,9 @@ const BaseNavItemSchema = z.object({ /** Badge text or count displayed on the navigation item (e.g. "3", "New") */ badge: z.union([z.string(), z.number()]).optional().describe('Badge text or count displayed on the item'), + /** Visual variant for the badge (consumed by objectui NavigationRenderer) */ + badgeVariant: z.enum(['default', 'secondary', 'destructive', 'outline']).optional().describe('Visual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit #1878/#1891/#1894).'), + /** * Visibility condition. * Formula expression returning boolean. @@ -263,11 +266,23 @@ export const GroupNavItemSchema = lazySchema(() => BaseNavItemSchema.extend({ // children property is added in the recursive definition below })); +/** + * 9. Separator Navigation Item + * A visual divider in the navigation list. Renders no target; declared to + * match the objectui renderer's `item.type === 'separator'` branch + * (inverse-drift fix, liveness audit #1878/#1891/#1894). + */ +const SeparatorNavItemSchema = lazySchema(() => z.object({ + type: z.literal('separator'), + id: SnakeCaseIdentifierSchema.optional().describe('Optional id for the separator'), + order: z.number().optional().describe('Sort order within the same level (lower = first)'), +})); + /** * Recursive Union of all navigation item types. * Allows constructing an unlimited-depth navigation tree. */ -export const NavigationItemSchema: z.ZodType = z.lazy(() => +export const NavigationItemSchema: z.ZodType = z.lazy(() => z.union([ ObjectNavItemSchema.extend({ children: z.array(NavigationItemSchema).optional().describe('Child navigation items (e.g. specific views)'), @@ -278,6 +293,7 @@ export const NavigationItemSchema: z.ZodType = z.lazy(() => ReportNavItemSchema, ActionNavItemSchema, ComponentNavItemSchema, + SeparatorNavItemSchema, GroupNavItemSchema.extend({ children: z.array(NavigationItemSchema).describe('Child navigation items'), }) @@ -324,6 +340,7 @@ export type NavigationContribution = z.infer z.object({ primaryColor: z.string().optional().describe('Primary theme color hex code'), + accentColor: z.string().optional().describe('Accent color hex code (highlights, active states). Declared to match the objectui ConsoleLayout read of branding.accentColor (inverse-drift fix, liveness audit #1878/#1891/#1894).'), logo: z.string().optional().describe('Custom logo URL for this app'), favicon: z.string().optional().describe('Custom favicon URL for this app'), })); diff --git a/packages/spec/src/ui/portal.zod.ts b/packages/spec/src/ui/portal.zod.ts index 7551bad12e..cf7de4f1ce 100644 --- a/packages/spec/src/ui/portal.zod.ts +++ b/packages/spec/src/ui/portal.zod.ts @@ -319,7 +319,7 @@ export const PortalSchema = lazySchema(() => z.object({ /** Whether the portal is active. */ active: z.boolean().optional().default(true), -})); +}).describe('Portal projection. [EXPERIMENTAL — not enforced] PortalSchema is not registered as an authorable metadata type; no dispatcher route family, auth scope, LayoutDispatcher, NavigationBuilder or ThemeProvider consumes it yet. The entire schema is a forward-looking design (framework #1294); authoring a portal today is a no-op (liveness audit #1878/#1893).')); // --------------------------------------------------------------------------- // Factory + types diff --git a/packages/spec/src/ui/theme.zod.ts b/packages/spec/src/ui/theme.zod.ts index 7d74b987c5..0f2e7dc490 100644 --- a/packages/spec/src/ui/theme.zod.ts +++ b/packages/spec/src/ui/theme.zod.ts @@ -223,7 +223,7 @@ export const ThemeSchema = lazySchema(() => z.object({ typography: TypographySchema.optional().describe('Typography settings'), /** Spacing */ - spacing: SpacingSchema.optional().describe('Spacing scale'), + spacing: SpacingSchema.optional().describe('Spacing scale. [EXPERIMENTAL — not enforced] generateThemeVars does not emit spacing tokens yet (liveness audit #1878/#1893).'), /** Border radius */ borderRadius: BorderRadiusSchema.optional().describe('Border radius scale'), @@ -232,7 +232,7 @@ export const ThemeSchema = lazySchema(() => z.object({ shadows: ShadowSchema.optional().describe('Box shadow effects'), /** Breakpoints */ - breakpoints: BreakpointsSchema.optional().describe('Responsive breakpoints'), + breakpoints: BreakpointsSchema.optional().describe('Responsive breakpoints. [EXPERIMENTAL — not enforced] generateThemeVars does not emit breakpoint tokens yet (liveness audit #1878/#1893).'), /** Animation */ animation: AnimationSchema.optional().describe('Animation settings'), @@ -254,16 +254,16 @@ export const ThemeSchema = lazySchema(() => z.object({ extends: z.string().optional().describe('Base theme to extend from'), /** Display density mode */ - density: DensityModeSchema.optional().describe('Display density: compact, regular, or spacious'), + density: DensityModeSchema.optional().describe('Display density: compact, regular, or spacious. [EXPERIMENTAL — not enforced] The theme engine does not consume theme-level density yet; view-level densityMode is a separate live setting (liveness audit #1878/#1893).'), /** WCAG contrast level requirement */ wcagContrast: WcagContrastLevelSchema.optional().describe('WCAG color contrast level (AA or AAA)'), /** Right-to-left language support */ - rtl: z.boolean().optional().describe('Enable right-to-left layout direction'), + rtl: z.boolean().optional().describe('Enable right-to-left layout direction. [EXPERIMENTAL — not enforced] No renderer reads theme.rtl yet (liveness audit #1878/#1893).'), /** Touch target accessibility configuration */ - touchTarget: TouchTargetConfigSchema.optional().describe('Touch target sizing defaults'), + touchTarget: TouchTargetConfigSchema.optional().describe('Touch target sizing defaults. [EXPERIMENTAL — not enforced] No renderer consumes touchTarget yet (liveness audit #1878/#1893).'), /** Keyboard navigation and focus management */ keyboardNavigation: FocusManagementSchema.optional().describe('Keyboard focus management settings'),