diff --git a/.changeset/adr-0115-docs-tail-corrections.md b/.changeset/adr-0115-docs-tail-corrections.md
new file mode 100644
index 0000000000..b35247b690
--- /dev/null
+++ b/.changeset/adr-0115-docs-tail-corrections.md
@@ -0,0 +1,4 @@
+---
+---
+
+docs(spec,kernel): #4093-series tail — the dev-plugin protocol header stops describing the retired stub design and points at #4149 (the enforce-or-remove evaluation for that declared-but-unconsumed schema family), and services-checklist.mdx gets a ten-fix accuracy pass (verified adversarially). Documentation only; releases nothing.
diff --git a/content/docs/kernel/services-checklist.mdx b/content/docs/kernel/services-checklist.mdx
index 3f9839d6d2..b45f69d440 100644
--- a/content/docs/kernel/services-checklist.mdx
+++ b/content/docs/kernel/services-checklist.mdx
@@ -56,7 +56,7 @@ The ObjectStack protocol defines **16 kernel services** registered via the `Core
| # | Service Name | Criticality | Methods | Status | Provider |
|:--|:-------------|:------------|:--------|:-------|:---------|
-| 1 | **metadata** | `core` | 7 | ⚠️ Framework | Kernel (in-memory) |
+| 1 | **metadata** | `core` | 8 | ⚠️ Framework | Kernel (in-memory) |
| 2 | **data** | `required` | 9 | ✅ Implemented | `@objectstack/objectql` |
| 3 | **analytics** | `optional` | 2 | ❌ Plugin Required | `@objectstack/service-analytics` |
| 4 | **auth** | `core` | — | 🟡 In Development | `@objectstack/plugin-auth` |
@@ -77,7 +77,7 @@ The ObjectStack protocol defines **16 kernel services** registered via the `Core
**Criticality Levels**
- **required**: System cannot start without this service
- **core**: Falls back to in-memory implementation with a warning if missing
-- **optional**: Feature disabled; API returns `501 Not Implemented` if missing
+- **optional**: Feature disabled; the API answers as an empty slot if missing (404, or the domain's 501)
---
@@ -97,6 +97,7 @@ The ObjectStack protocol defines **16 kernel services** registered via the `Core
| `getMetaItems` | `GetMetaItemsRequest → GetMetaItemsResponse` | ✅ |
| `getMetaItem` | `GetMetaItemRequest → GetMetaItemResponse` | ✅ |
| `saveMetaItem` | `SaveMetaItemRequest → SaveMetaItemResponse` | ✅ |
+| `deleteMetaItem` | `DeleteMetaItemRequest → DeleteMetaItemResponse` | ✅ |
| `getMetaItemCached` | `GetMetaItemCachedRequest → GetMetaItemCachedResponse` | ✅ |
| `getUiView` | `GetUiViewRequest → GetUiViewResponse` | ✅ |
@@ -106,7 +107,7 @@ The metadata service is a **framework** — it works with an in-memory `SchemaRe
| Gap | Description | Priority |
|:----|:------------|:--------:|
-| **DB Persistence** | Metadata is only in memory; no save-to-database path exists | P0 |
+| **DB Persistence** | Shipped: `MetadataPlugin` (`@objectstack/metadata`) persists to `sys_metadata`; only the kernel's in-memory fallback is non-persistent | Shipped |
| **Multi-instance Sync** | No mechanism to share metadata changes across instances | P1 |
| **Migration / Versioning** | No schema diff or migration tooling | P1 |
| **Hot Reload** | Metadata changes require restart | P2 |
@@ -133,7 +134,7 @@ no message. Below is the former — the fallback case:
},
"auth": {
"enabled": false, "status": "unavailable",
- "message": "Install an auth plugin to enable"
+ "message": "Install a auth plugin to enable"
}
}
}
@@ -158,7 +159,9 @@ empty. The rule is enforced by one predicate (`isServiceServeable`) shared by
the service domains, the route-mount gate, and both discovery builders, so what
is advertised and what is served cannot disagree. It applies to the
dispatcher-owned domains: `/analytics`, `/automation`, `/notifications`, `/ai`,
-`/storage`, `/i18n`.
+`/i18n`. (`/storage` is no longer a dispatcher domain — the bridge was retired
+in #4087 and `service-storage` mounts `/api/v1/storage` itself — but its route
+advertisement is still gated on the same predicate.)
The `services` map still reports a registered stub as
`{ enabled: true, status: "stub", handlerReady: false }` rather than collapsing
@@ -196,10 +199,9 @@ than "install a plugin".
| Driver | Package | CRUD | Aggregation | Ready |
|:-------|:--------|:----:|:-----------:|:-----:|
| InMemory | `@objectstack/driver-memory` | ✅ | ✅ | Dev/Test |
-| PostgreSQL | TBD | — | — | — |
-| MySQL | TBD | — | — | — |
-| MongoDB | TBD | — | — | — |
-| SQLite | TBD | — | — | — |
+| PostgreSQL / MySQL / SQLite | `@objectstack/driver-sql` (Knex) | ✅ | ✅ | ✅ |
+| MongoDB | `@objectstack/driver-mongodb` | ✅ | ✅ | ✅ |
+| SQLite (WASM) | `@objectstack/driver-sqlite-wasm` | ✅ | ✅ | Browser/WebContainer |
---
@@ -221,8 +223,9 @@ discovery reports `analytics: { enabled: false, status: "unavailable" }`.
`analytics` dev stub, and the dispatcher treats a slot filled by any
self-declared stub (`handlerReady: false`, ADR-0076 D12) exactly like an empty
one — routes unmounted, request 404. To use analytics locally, install the real
-engine; `@objectstack/service-analytics` runs an InMemory strategy, so it needs
-no database of its own.
+engine; `@objectstack/service-analytics` works against the in-memory driver
+(via its ObjectQL strategy, or `InMemoryStrategy` injected from
+`@objectstack/driver-memory`), so it needs no database of its own.
**And it is no longer analytics-only** (#4058 step 2): every dispatcher-owned
domain now gates on `handlerReady`, so a slot occupied by a self-declared `stub`
@@ -298,12 +301,14 @@ Trigger engine, event triggers from ObjectQL hooks, flow executor, scheduled tri
`aiNlq`, `aiSuggest`, `aiInsights`
-Declared only. All three are **optional** protocol methods (`aiNlq?` …) that no
-service in any repo implements, so the `/ai/{nlq,suggest,insights}` routes they
-back are mounted by nothing. The `client.ai` namespace that called them was
-removed in v17 (#3718). The AI service that does exist (`service-ai`) serves a
-different set — chat, complete, models, conversations — through none of these
-methods, so this entry describes a contract with no implementer on either side.
+Removed. These three were **optional** protocol methods (`aiNlq?` …) that no
+service in any repo ever implemented — the `/ai/{nlq,suggest,insights}` routes
+they backed were mounted by nothing and 404ed for their whole life. In v17 the
+`AiProtocol` contract, its schemas, and the `client.ai.{nlq,suggest,insights}`
+methods that called them were deleted outright (#3718). The AI service that
+does exist (`service-ai`, Cloud/EE) serves a different surface — chat,
+complete, models, conversations, agents — and `client.ai` was rebuilt against
+those real routes, so this entry describes a contract that no longer exists.
### 11. i18n — 3 methods
@@ -380,7 +385,7 @@ AppPlugin will:
| **file-storage** | Unified upload/download/delete. Drivers: local FS, S3, MinIO. |
| **search** | Full-text search. Drivers: in-memory, Elasticsearch, Meilisearch. |
| **cache** | General-purpose cache. In-memory fallback; Redis via `@objectstack/service-cache`. |
-| **queue** | Message queue. In-memory fallback; BullMQ / Redis via `@objectstack/service-queue`. |
+| **queue** | Message queue. In-memory fallback; durable DB-backed adapter via `@objectstack/service-queue` (no BullMQ/Redis adapter is shipped). |
| **job** | Scheduled task execution. In-memory fallback; cron-based, concurrency control. |
---
diff --git a/content/docs/references/kernel/dev-plugin.mdx b/content/docs/references/kernel/dev-plugin.mdx
index 5e4955bf9a..f523f7056f 100644
--- a/content/docs/references/kernel/dev-plugin.mdx
+++ b/content/docs/references/kernel/dev-plugin.mdx
@@ -7,31 +7,35 @@ description: Dev Plugin protocol schemas
# Dev Mode Plugin Protocol
-Defines the schema for a development-mode plugin that automatically enables
+Declared configuration vocabulary for a development-mode plugin: per-service
-all platform services for local simulation. When loaded as a `devPlugin`,
+dev strategies, fixture loading, developer tooling, presets.
-the kernel bootstraps every subsystem (data, UI, API, auth, events, jobs, …)
+⚠️ **Declared, not implemented — pending enforce-or-remove (#4149).**
-using in-memory or stub implementations so that developers can exercise the
+The shipped `@objectstack/plugin-dev` consumes its own `DevPluginOptions`
-full stack without external dependencies.
+interface, NOT this schema, and none of the surfaces below (presets,
-Design goals:
+fixtures, dev-tools dashboard, per-service strategies, simulated latency)
-- Zero-config by default: `devPlugins: ['@objectstack/plugin-dev']`
+exist in it. Since ADR-0115 it is an **assembly** plugin: it wires the real
-- Every service can be overridden or disabled individually
+platform plugins for local development and registers no stub or simulated
-- Preset profiles (minimal / standard / full) for common scenarios
+services — an unfilled slot answers exactly as it does in production. The
+
+`strategy: 'stub'` value in particular describes a behaviour the platform
-Inspired by:
+has retired. Do not build against this file until #4149 resolves it.
-- Spring Boot DevTools (auto-configuration)
+Original design goals, kept for the #4149 evaluation:
-- Next.js Dev Server (HMR + mock APIs)
+- Zero-config by default: `devPlugins: ['@objectstack/plugin-dev']`
+
+- Every service can be overridden or disabled individually
-- Vite Plugin Dev Mode (instant startup)
+- Preset profiles (minimal / standard / full) for common scenarios
**Source:** `packages/spec/src/kernel/dev-plugin.zod.ts`
diff --git a/packages/spec/src/kernel/dev-plugin.zod.ts b/packages/spec/src/kernel/dev-plugin.zod.ts
index 8d0d66cd34..196f99c499 100644
--- a/packages/spec/src/kernel/dev-plugin.zod.ts
+++ b/packages/spec/src/kernel/dev-plugin.zod.ts
@@ -5,21 +5,23 @@ import { z } from 'zod';
/**
* # Dev Mode Plugin Protocol
*
- * Defines the schema for a development-mode plugin that automatically enables
- * all platform services for local simulation. When loaded as a `devPlugin`,
- * the kernel bootstraps every subsystem (data, UI, API, auth, events, jobs, …)
- * using in-memory or stub implementations so that developers can exercise the
- * full stack without external dependencies.
+ * Declared configuration vocabulary for a development-mode plugin: per-service
+ * dev strategies, fixture loading, developer tooling, presets.
*
- * Design goals:
+ * ⚠️ **Declared, not implemented — pending enforce-or-remove (#4149).**
+ * The shipped `@objectstack/plugin-dev` consumes its own `DevPluginOptions`
+ * interface, NOT this schema, and none of the surfaces below (presets,
+ * fixtures, dev-tools dashboard, per-service strategies, simulated latency)
+ * exist in it. Since ADR-0115 it is an **assembly** plugin: it wires the real
+ * platform plugins for local development and registers no stub or simulated
+ * services — an unfilled slot answers exactly as it does in production. The
+ * `strategy: 'stub'` value in particular describes a behaviour the platform
+ * has retired. Do not build against this file until #4149 resolves it.
+ *
+ * Original design goals, kept for the #4149 evaluation:
* - Zero-config by default: `devPlugins: ['@objectstack/plugin-dev']`
* - Every service can be overridden or disabled individually
* - Preset profiles (minimal / standard / full) for common scenarios
- *
- * Inspired by:
- * - Spring Boot DevTools (auto-configuration)
- * - Next.js Dev Server (HMR + mock APIs)
- * - Vite Plugin Dev Mode (instant startup)
*/
// ============================================================================