Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .changeset/kernel-context-preview-mode-retired.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
---
"@objectstack/spec": minor
---

feat(spec): retire preview mode — the `'preview'` RuntimeMode value and the whole `KernelContext.previewMode` / `PreviewModeConfig` block (#11846, ADR-0049)

<!-- adr-0087: registered kernel-context-preview-mode-retired -->

**BREAKING** accept-set narrowing and export removal, landing after the
v17.0.0 cut (the lockstep launch-window convention ships it as `minor`; the
prescription is registered under protocol major 18 —
`RETIRED_KEYS_BY_MAJOR[18]` for both walked-shape keys,
`RETIRED_DEFS_BY_MAJOR[18]` for the def, plus the D3 semantic entry
`kernel-context-preview-mode-retired` — where `os migrate meta` users will
look).

The declaration was the sharpest declared-≠-enforced shape on a SECURITY
surface: the schema promised "bypass auth, simulate admin identity" and named
a production guard "the runtime must enforce", and NO code path implemented
either half. Measured zero consumers in objectstack, objectui and cloud
(cloud#1651, closed 2026-08-26 with positive controls: `RuntimeMode` has zero
hits repo-wide there, and `ArtifactKernelFactory` — where preview auto-login
would live if anywhere — has 20+ hits and never touches `previewMode`;
re-verified in objectstack at dispatch, 2026-08-27). An author — very often
an AI — could write the six-key block per the reference docs, parse cleanly,
and get no behaviour and no diagnostic.

FROM → TO:

- `mode: 'preview'` → *(removed value)* — `mode` defaults to `'production'`;
use `'development'` for local demo work. The rejection carries the
prescription via the enum's own error map (the `HookBodyCapability`
precedent); every other mode keeps zod's own message.
- `previewMode: { … }` on `KernelContext` / `TenantRuntimeContext` →
*(removed key)* — tombstoned with `retiredKey()` (the schemas are not
`.strict()`, so a bare deletion would be a silent strip): authoring it is
now a `tsc` error and a parse error carrying the prescription.
- `PreviewModeConfigSchema` / `PreviewModeConfig` / `PreviewModeConfigParsed`
→ *(removed — no replacement)*. The def described behaviour no layer
implemented; an exported value schema with no consumer reads as a
capability (#3950).

One-line fix: delete the key and the value — neither ever changed runtime
behaviour, so removing them changes nothing observable. Preview deployment
ROUTING is untouched: `OS_PREVIEW_MODE` / `OS_PREVIEW_BASE_DOMAINS` keep
working exactly as documented (deployment routing, never identity). If a
preview experience becomes a product capability it re-declares fresh, with
the production-posture hard-refusal as the first-landed half (#11846 ruling
record, maintainer 2026-08-27).

The retirement kit:

- tombstones at both declarations (`kernel/KernelContext:previewMode` and the
`.extend()` copy `kernel/TenantRuntimeContext:previewMode`, both in
`RETIRED_KEYS_BY_MAJOR[18]`); the enum value's prescription on
`RuntimeMode`'s error map (enum-VALUE retirements register nothing in
RETIRED_KEYS_BY_MAJOR and leave the surface ratchets byte-identical)
- whole-def deletion `kernel/PreviewModeConfig` in `RETIRED_DEFS_BY_MAJOR[18]`
(manifest key deliberately removed; the #4725 gate adjudicated it)
- deliberately NO D2 conversion: a kernel context is constructed by host code
at boot — not a stack collection member, never a `sys_metadata` row — so
the conversion chain has no seam that would ever see one (the
`kernel/Manifest:loading` disposition); the D3 semantic entry carries the
prescription
- pin tests (`kernel/preview-mode-retirement.test.ts`): both rejection sites
flip from silent parse to the prescription; zero holders for all 3 retired
export names on every public entry; the carrier schemas survive
10 changes: 5 additions & 5 deletions content/docs/references/index.mdx
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
---
title: Protocol Reference
description: Every schema published by @objectstack/spec — 1605 schemas across 14 protocol modules
description: Every schema published by @objectstack/spec — 1604 schemas across 14 protocol modules
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand All@@ -26,14 +26,14 @@ counts are sums of the rows they head. Regenerate with
| [Data Protocol](/docs/references/data) | 29 | 166 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
| [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. |
| [Integration Protocol](/docs/references/integration) | 1 | 27 | The single connector protocol (ADR-0097) — catalog descriptors and provider-bound instances. |
| [Kernel Protocol](/docs/references/kernel) | 31 | 171 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
| [Kernel Protocol](/docs/references/kernel) | 31 | 170 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
| [QA Protocol](/docs/references/qa) | 1 | 8 | Declarative test suites — scenarios, steps, actions and assertions. |
| [Security Protocol](/docs/references/security) | 5 | 29 | Permission sets, row-level security, sharing rules, tenancy posture. |
| [Shared Protocol](/docs/references/shared) | 8 | 32 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
| [System Protocol](/docs/references/system) | 36 | 291 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
| [UI Protocol](/docs/references/ui) | 16 | 152 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
| **Total** | **201** | **1605** | 14 protocol modules |
| **Total** | **201** | **1604** | 14 protocol modules |

---

Expand DownExpand Up@@ -217,15 +217,15 @@ The single connector protocol (ADR-0097) — catalog descriptors and provider-bo

## Kernel Protocol

**Source:** `packages/spec/src/kernel/` · **Import:** `@objectstack/spec/kernel` · **31 pages, 171 schemas**
**Source:** `packages/spec/src/kernel/` · **Import:** `@objectstack/spec/kernel` · **31 pages, 170 schemas**

Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry.

| File | Schemas |
| :--- | :--- |
| [`cli-extension.zod.ts`](/docs/references/kernel/cli-extension) | `OclifPluginConfig` |
| [`cluster.zod.ts`](/docs/references/kernel/cluster) | `ClusterCapabilityConfig`, `ClusterDriver`, `ClusterTenantIsolation`, `EventClusterOptions`, `EventDeliverySemantics`, `EventScope`, `MetadataChangeOperation`, `ServiceClusterAnnotations`, `ServiceClusterScope`, `ServiceLeaderStrategy` |
| [`context.zod.ts`](/docs/references/kernel/context) | `KernelContext`, `PreviewModeConfig`, `RuntimeMode`, `TenantRuntimeContext` |
| [`context.zod.ts`](/docs/references/kernel/context) | `KernelContext`, `RuntimeMode`, `TenantRuntimeContext` |
| [`dependency-resolution.zod.ts`](/docs/references/kernel/dependency-resolution) | `DependencyResolutionResult`, `DependencyStatusEnum`, `RequiredAction`, `ResolvedDependency` |
| [`events/bus.zod.ts`](/docs/references/kernel/events-bus) | `EventBusConfig` |
| [`events/core.zod.ts`](/docs/references/kernel/events-core) | `Event`, `EventMetadata`, `EventPriority`, `EventTypeDefinition` |
Expand Down
54 changes: 6 additions & 48 deletions content/docs/references/kernel/context.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,18 +5,15 @@ description: Context protocol schemas

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}

Runtime Mode Enum
Defines the operating mode of the kernel

<Callout type="info">
**Source:** `packages/spec/src/kernel/context.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { KernelContextSchema, PreviewModeConfigSchema, RuntimeMode, TenantRuntimeContextSchema } from '@objectstack/spec/kernel';
import type { KernelContext, PreviewModeConfig, RuntimeMode, TenantRuntimeContext } from '@objectstack/spec/kernel';
import { KernelContextSchema, RuntimeMode, TenantRuntimeContextSchema } from '@objectstack/spec/kernel';
import type { KernelContext, RuntimeMode, TenantRuntimeContext } from '@objectstack/spec/kernel';

// Validate data
const result = KernelContextSchema.parse(data);
Expand All@@ -31,41 +28,14 @@ const result = KernelContextSchema.parse(data);
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **instanceId** | `string` | ✅ | Unique UUID for this running kernel process |
| **mode** | `Enum<'development' \| 'production' \| 'test' \| 'provisioning' \| 'preview'>` | optional (default: `"production"`) | Kernel operating mode |
| **mode** | `Enum<'development' \| 'production' \| 'test' \| 'provisioning'>` | optional (default: `"production"`) | Kernel operating mode |
| **version** | `string` | ✅ | Kernel version |
| **appName** | `string` | optional | Host application name |
| **cwd** | `string` | ✅ | Current working directory |
| **workspaceRoot** | `string` | optional | Workspace root if different from cwd |
| **startTime** | `integer` | ✅ | Boot timestamp (ms) |
| **features** | `Record<string, boolean>` | optional (default: `{}`) | Global feature toggles |
| **previewMode** | `{ autoLogin: boolean; simulatedRole: Enum<'admin' \| 'user' \| 'viewer'>; simulatedUserName: string; readOnly: boolean; … }` | optional | Preview/demo mode configuration (used when mode is "preview") |

### Nested Shape: `KernelContext.previewMode`

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **autoLogin** | `boolean` | optional (default: `true`) | Auto-login as simulated user, skipping login/registration pages |
| **simulatedRole** | `Enum<'admin' \| 'user' \| 'viewer'>` | optional (default: `"admin"`) | Permission role for the simulated preview user |
| **simulatedUserName** | `string` | optional (default: `"Preview User"`) | Display name for the simulated preview user |
| **readOnly** | `boolean` | optional (default: `false`) | Restrict the preview session to read-only operations |
| **expiresInSeconds** | `integer` | optional (default: `0`) | Preview session duration in seconds (0 = no expiration) |
| **bannerMessage** | `string` | optional | Banner message displayed in the UI during preview mode |


---

## PreviewModeConfig

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **autoLogin** | `boolean` | optional (default: `true`) | Auto-login as simulated user, skipping login/registration pages |
| **simulatedRole** | `Enum<'admin' \| 'user' \| 'viewer'>` | optional (default: `"admin"`) | Permission role for the simulated preview user |
| **simulatedUserName** | `string` | optional (default: `"Preview User"`) | Display name for the simulated preview user |
| **readOnly** | `boolean` | optional (default: `false`) | Restrict the preview session to read-only operations |
| **expiresInSeconds** | `integer` | optional (default: `0`) | Preview session duration in seconds (0 = no expiration) |
| **bannerMessage** | `string` | optional | Banner message displayed in the UI during preview mode |
| **previewMode** | `never` | optional | [REMOVED] `context.previewMode` was removed in @objectstack/spec 17 (#11846, ADR-0049 enforce-or-remove) — nothing ever read the block: none of its six keys (`autoLogin`, `simulatedRole`, `simulatedUserName`, `readOnly`, `expiresInSeconds`, `bannerMessage`) had a consumer in any repo, so an authored block parsed cleanly and configured NOTHING, while its own docstring promised an auth bypass ("skips authentication screens", "simulates an admin identity") and named a production guard no runtime ever received. Delete the key. Preview/demo deployments belong to the deployment layer, which owns auth per-project (`ArtifactKernelFactory` in the cloud distribution); `OS_PREVIEW_MODE` stays there as a routing-only switch. If a preview experience becomes a product capability it re-declares fresh, with the production-posture hard-refusal as the first-landed half (#11846 ruling record). |


---
Expand All@@ -80,7 +50,6 @@ Kernel operating mode
* `production`
* `test`
* `provisioning`
* `preview`


---
Expand All@@ -94,31 +63,20 @@ Tenant-aware kernel runtime context
| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **instanceId** | `string` | ✅ | Unique UUID for this running kernel process |
| **mode** | `Enum<'development' \| 'production' \| 'test' \| 'provisioning' \| 'preview'>` | optional (default: `"production"`) | Kernel operating mode |
| **mode** | `Enum<'development' \| 'production' \| 'test' \| 'provisioning'>` | optional (default: `"production"`) | Kernel operating mode |
| **version** | `string` | ✅ | Kernel version |
| **appName** | `string` | optional | Host application name |
| **cwd** | `string` | ✅ | Current working directory |
| **workspaceRoot** | `string` | optional | Workspace root if different from cwd |
| **startTime** | `integer` | ✅ | Boot timestamp (ms) |
| **features** | `Record<string, boolean>` | optional (default: `{}`) | Global feature toggles |
| **previewMode** | `{ autoLogin: boolean; simulatedRole: Enum<'admin' \| 'user' \| 'viewer'>; simulatedUserName: string; readOnly: boolean; … }` | optional | Preview/demo mode configuration (used when mode is "preview") |
| **previewMode** | `never` | optional | [REMOVED] `context.previewMode` was removed in @objectstack/spec 17 (#11846, ADR-0049 enforce-or-remove) — nothing ever read the block: none of its six keys (`autoLogin`, `simulatedRole`, `simulatedUserName`, `readOnly`, `expiresInSeconds`, `bannerMessage`) had a consumer in any repo, so an authored block parsed cleanly and configured NOTHING, while its own docstring promised an auth bypass ("skips authentication screens", "simulates an admin identity") and named a production guard no runtime ever received. Delete the key. Preview/demo deployments belong to the deployment layer, which owns auth per-project (`ArtifactKernelFactory` in the cloud distribution); `OS_PREVIEW_MODE` stays there as a routing-only switch. If a preview experience becomes a product capability it re-declares fresh, with the production-posture hard-refusal as the first-landed half (#11846 ruling record). |
| **tenantId** | `string` | ✅ | Resolved tenant identifier |
| **tenantPlan** | `Enum<'free' \| 'pro' \| 'enterprise'>` | ✅ | Tenant subscription plan |
| **tenantRegion** | `string` | optional | Tenant deployment region |
| **tenantDbUrl** | `string` | ✅ | Tenant database connection URL |
| **tenantQuotas** | `{ maxUsers?: integer; maxStorage?: integer; apiRateLimit?: integer; maxObjects?: integer; … }` | optional | Tenant resource quotas |

### Nested Shape: `TenantRuntimeContext.previewMode`

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **autoLogin** | `boolean` | optional (default: `true`) | Auto-login as simulated user, skipping login/registration pages |
| **simulatedRole** | `Enum<'admin' \| 'user' \| 'viewer'>` | optional (default: `"admin"`) | Permission role for the simulated preview user |
| **simulatedUserName** | `string` | optional (default: `"Preview User"`) | Display name for the simulated preview user |
| **readOnly** | `boolean` | optional (default: `false`) | Restrict the preview session to read-only operations |
| **expiresInSeconds** | `integer` | optional (default: `0`) | Preview session duration in seconds (0 = no expiration) |
| **bannerMessage** | `string` | optional | Banner message displayed in the UI during preview mode |

### Nested Shape: `TenantRuntimeContext.tenantQuotas`

| Property | Type | Required | Description |
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -261,7 +261,7 @@ directory rather than per file.
| `cloud/` | 83 |
| `identity/` | 32 |
| `integration/` | 10 |
| `kernel/` | 272 |
| `kernel/` | 271 |
| `qa/` | 6 |
| `shared/` | 20 |
| `system/` | 364 |
3 changes: 0 additions & 3 deletions packages/spec/api-surface/kernel.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -356,9 +356,6 @@
"PluginVersionMetadata (type)",
"PluginVersionMetadataParsed (type)",
"PluginVersionMetadataSchema (const)",
"PreviewModeConfig (type)",
"PreviewModeConfigParsed (type)",
"PreviewModeConfigSchema (const)",
"ProtocolFeature (type)",
"ProtocolFeatureParsed (type)",
"ProtocolFeatureSchema (const)",
Expand Down
5 changes: 0 additions & 5 deletions packages/spec/authorable-defaults/kernel.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,11 +119,6 @@
"kernel/PluginTrustScore:badges = []",
"kernel/PluginVendor:trustLevel = \"unverified\"",
"kernel/PluginVendor:verified = false",
"kernel/PreviewModeConfig:autoLogin = true",
"kernel/PreviewModeConfig:expiresInSeconds = 0",
"kernel/PreviewModeConfig:readOnly = false",
"kernel/PreviewModeConfig:simulatedRole = \"admin\"",
"kernel/PreviewModeConfig:simulatedUserName = \"Preview User\"",
"kernel/ProtocolFeature:enabled = true",
"kernel/RealTimeNotificationConfig:enabled = true",
"kernel/RealTimeNotificationConfig:eventPattern = \"*\"",
Expand Down
10 changes: 2 additions & 8 deletions packages/spec/authorable-surface/kernel.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -250,7 +250,7 @@
"kernel/KernelContext:features",
"kernel/KernelContext:instanceId",
"kernel/KernelContext:mode",
"kernel/KernelContext:previewMode",
"kernel/KernelContext:previewMode [RETIRED]",
"kernel/KernelContext:startTime",
"kernel/KernelContext:version",
"kernel/KernelContext:workspaceRoot",
Expand DownExpand Up@@ -654,12 +654,6 @@
"kernel/PluginVersionMetadata:support",
"kernel/PluginVersionMetadata:version",
"kernel/PluginVersionMetadata:versionString",
"kernel/PreviewModeConfig:autoLogin",
"kernel/PreviewModeConfig:bannerMessage",
"kernel/PreviewModeConfig:expiresInSeconds",
"kernel/PreviewModeConfig:readOnly",
"kernel/PreviewModeConfig:simulatedRole",
"kernel/PreviewModeConfig:simulatedUserName",
"kernel/ProtocolFeature:deprecatedSince",
"kernel/ProtocolFeature:description",
"kernel/ProtocolFeature:enabled",
Expand DownExpand Up@@ -801,7 +795,7 @@
"kernel/TenantRuntimeContext:features",
"kernel/TenantRuntimeContext:instanceId",
"kernel/TenantRuntimeContext:mode",
"kernel/TenantRuntimeContext:previewMode",
"kernel/TenantRuntimeContext:previewMode [RETIRED]",
"kernel/TenantRuntimeContext:startTime",
"kernel/TenantRuntimeContext:tenantDbUrl",
"kernel/TenantRuntimeContext:tenantId",
Expand Down
3 changes: 0 additions & 3 deletions packages/spec/export-origins/kernel.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -356,9 +356,6 @@
"PluginVersionMetadata": "src/kernel/plugin-versioning.zod.ts#PluginVersionMetadata (type)",
"PluginVersionMetadataParsed": "src/kernel/plugin-versioning.zod.ts#PluginVersionMetadataParsed (type)",
"PluginVersionMetadataSchema": "src/kernel/plugin-versioning.zod.ts#PluginVersionMetadataSchema (const)",
"PreviewModeConfig": "src/kernel/context.zod.ts#PreviewModeConfig (type)",
"PreviewModeConfigParsed": "src/kernel/context.zod.ts#PreviewModeConfigParsed (type)",
"PreviewModeConfigSchema": "src/kernel/context.zod.ts#PreviewModeConfigSchema (const)",
"ProtocolFeature": "src/kernel/plugin-capability.zod.ts#ProtocolFeature (type)",
"ProtocolFeatureParsed": "src/kernel/plugin-capability.zod.ts#ProtocolFeatureParsed (type)",
"ProtocolFeatureSchema": "src/kernel/plugin-capability.zod.ts#ProtocolFeatureSchema (const)",
Expand Down
1 change: 0 additions & 1 deletion packages/spec/json-schema.manifest/kernel.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,7 +128,6 @@
"kernel/PluginTrustScore",
"kernel/PluginVendor",
"kernel/PluginVersionMetadata",
"kernel/PreviewModeConfig",
"kernel/ProtocolFeature",
"kernel/ProtocolReference",
"kernel/ProtocolVersion",
Expand Down
Loading
Loading