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
13 changes: 13 additions & 0 deletions .changeset/23216-routes-retire-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'@objectstack/spec': patch
---

Clause-②: no

The `manifest.contributes.routes` and `App.apis` retire messages (and the published
`plugin-manifest-contributes-routes-retired` migration text) no longer send app authors to an
imperative `http.server` route registered on `kernel:ready`. An app declares its endpoint under
`defineStack({ apis })` (`type: 'object_operation'` or `'flow'`, ADR-0121), computes in a flow,
and registers code as a stack function (`defineStack({ functions })`) or a connector. The
`http.server` service itself is unchanged: platform plugins keep mounting their own doors on it.
No key is added or removed.
15 changes: 9 additions & 6 deletions content/docs/references/api/dispatcher.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ The dispatcher is the central routing component that:
1. Matches incoming request URLs against registered route prefixes
2. Delegates to the corresponding CoreService implementation
3. Returns 503 Service Unavailable when a service is not registered
4. Serves prefixes registered by the kernel services above. Plugins that need
a code handler mount it imperatively on the `http.server` service (resolve
it from the plugin context on `kernel:ready`) — the manifest's
`contributes.routes` key was removed in @objectstack/spec 17 (commit bc56e1881):
nothing ever read it, and authoring it is now a tsc error and a parse
error carrying that prescription.
4. Serves prefixes registered by the kernel services above. The `http.server`
service is the PLATFORM plugins' own door-building primitive, not an
app-author surface: an app declares its endpoint under `defineStack({ apis })`
(`type: 'object_operation'` or `'flow'`, ADR-0121), computes in a flow, and
registers code as a stack function (`defineStack({ functions })`) or a
connector. The manifest's `contributes.routes` key was removed in
@objectstack/spec 17 (commit bc56e1881): nothing ever read it, and
authoring it is now a tsc error and a parse error carrying that
prescription.

Architecture alignment:
- Kubernetes: API server aggregation layer
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/api/metadata.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const result = AppDefinitionResponseSchema.parse(data);
| **homePageId** | `never` | optional | [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. |
| **requiredPermissions** | `string[]` | optional | Permissions required to access this app |
| **objects** | `never` | optional | [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. |
| **apis** | `never` | optional | [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. |
| **apis** | `never` | optional | [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. An endpoint whose work needs CODE still lands here: compute in a flow and register the code as a stack function (`defineStack({ functions })`) or a connector — an app does not mount routes on `http.server`, and the manifest `contributes.routes` key was removed in @objectstack/spec 17 (nothing ever read it; 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. |
| **sharing** | `never` | optional | [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. |
| **embed** | `never` | optional | [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. |
| **mobileNavigation** | `never` | optional | [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. |
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/api/package-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ Install package request
| **drivers** | `never` | optional | [REMOVED] `manifest.contributes.drivers` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — it never had an effect: a storage driver is wired by registering a kernel SERVICE named `driver.*` (the objectql plugin picks it up and calls `registerDriver`), and its only in-repo author was registered that way, not by this declaration. Delete the key. |
| **fieldTypes** | `never` | optional | [REMOVED] `manifest.contributes.fieldTypes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — there is no `registerFieldType` seam anywhere: the declaration advertised an extension point the platform does not have, so authoring it configured nothing. Delete the key. The field-type vocabulary is the spec `FieldType` enum; extending it is a spec change, not a manifest declaration. |
| **functions** | `never` | optional | [REMOVED] `manifest.contributes.functions` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it; ObjectQL functions declared here were never registered. Delete the key. Declare functions on the stack (`defineStack({ functions: […] })`), which the hook binder registers via `engine.registerFunction`. |
| **routes** | `never` | optional | [REMOVED] `manifest.contributes.routes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the HttpDispatcher never registered a prefix from the declaration, so an entry here parsed cleanly and served nothing while published material kept recommending it. Delete the key. A route that needs real handler CODE is mounted imperatively: resolve the `http.server` service from the plugin context and register the handler on `kernel:ready`. A declarative endpoint over a pipeline the platform already runs (query/return records, trigger a flow) is `defineStack({ apis })`. |
| **routes** | `never` | optional | [REMOVED] `manifest.contributes.routes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the HttpDispatcher never registered a prefix from the declaration, so an entry here parsed cleanly and served nothing while published material kept recommending it. Delete the key. An app does not mount routes on `http.server` — that service is the platform's own door-building primitive, and a code-mounted route gets no caller identity, auth gate, rate limit, namespace carve-out or OpenAPI entry. Declare the endpoint under `defineStack({ apis })` (`type: 'object_operation'` or `'flow'`, ADR-0121), compute in a flow, and register code as a stack function (`defineStack({ functions })`) or a connector. |
| **commands** | `never` | optional | [REMOVED] `manifest.contributes.commands` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — the CLI never resolved commands from this declaration: commands are auto-discovered through oclif's native plugin system (the plugin package declares an `oclif` section in its own `package.json`; see `cli-extension.zod.ts`), and the `objectstack.config.ts` plugins array no longer determines CLI commands. Delete the key. |

### Nested Shape: `PackageInstallBody[option 2].data[number]`
Expand Down
12 changes: 7 additions & 5 deletions content/docs/references/api/plugin-rest-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ Architecture Alignment:
- Microsoft Dynamics: Web API with entity operations
- Strapi: Auto-generated REST endpoints from schemas

**Serving routes from a plugin (imperative `http.server` mount)**
**Serving routes from a platform plugin (imperative `http.server` mount)**
```typescript
// Routes are mounted in CODE — resolve the `http.server` service from the
// plugin context and register handlers on `kernel:ready` (the service is
// registered by plugin-hono-server; `examples/app-showcase`'s
// recalc-endpoint is a real consumer of this exact shape). The worked
// A PLATFORM plugin mounts its routes in CODE — resolve the `http.server`
// service from the plugin context and register handlers on `kernel:ready`
// (the service is registered by plugin-hono-server). This is the platform's
// own door-building primitive, not an app-author surface: an app declares
// `defineStack({ apis })`, computes in a flow, and registers code as a stack
// function or a connector. The worked
// manifest example that used to sit here declared `contributes.routes`,
// which was removed in @objectstack/spec 17 (commit bc56e1881): nothing ever read
// it, so every route it showed parsed cleanly and served nothing.
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/kernel/manifest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Install mode: managed (registered as code, upgradeable, sealed) | unmanaged (cop
| **drivers** | `never` | optional | [REMOVED] `manifest.contributes.drivers` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — it never had an effect: a storage driver is wired by registering a kernel SERVICE named `driver.*` (the objectql plugin picks it up and calls `registerDriver`), and its only in-repo author was registered that way, not by this declaration. Delete the key. |
| **fieldTypes** | `never` | optional | [REMOVED] `manifest.contributes.fieldTypes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — there is no `registerFieldType` seam anywhere: the declaration advertised an extension point the platform does not have, so authoring it configured nothing. Delete the key. The field-type vocabulary is the spec `FieldType` enum; extending it is a spec change, not a manifest declaration. |
| **functions** | `never` | optional | [REMOVED] `manifest.contributes.functions` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it; ObjectQL functions declared here were never registered. Delete the key. Declare functions on the stack (`defineStack({ functions: […] })`), which the hook binder registers via `engine.registerFunction`. |
| **routes** | `never` | optional | [REMOVED] `manifest.contributes.routes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the HttpDispatcher never registered a prefix from the declaration, so an entry here parsed cleanly and served nothing while published material kept recommending it. Delete the key. A route that needs real handler CODE is mounted imperatively: resolve the `http.server` service from the plugin context and register the handler on `kernel:ready`. A declarative endpoint over a pipeline the platform already runs (query/return records, trigger a flow) is `defineStack({ apis })`. |
| **routes** | `never` | optional | [REMOVED] `manifest.contributes.routes` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the HttpDispatcher never registered a prefix from the declaration, so an entry here parsed cleanly and served nothing while published material kept recommending it. Delete the key. An app does not mount routes on `http.server` — that service is the platform's own door-building primitive, and a code-mounted route gets no caller identity, auth gate, rate limit, namespace carve-out or OpenAPI entry. Declare the endpoint under `defineStack({ apis })` (`type: 'object_operation'` or `'flow'`, ADR-0121), compute in a flow, and register code as a stack function (`defineStack({ functions })`) or a connector. |
| **commands** | `never` | optional | [REMOVED] `manifest.contributes.commands` was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — the CLI never resolved commands from this declaration: commands are auto-discovered through oclif's native plugin system (the plugin package declares an `oclif` section in its own `package.json`; see `cli-extension.zod.ts`), and the `objectstack.config.ts` plugins array no longer determines CLI commands. Delete the key. |

### Nested Shape: `Manifest.data[number]`
Expand Down
Loading
Loading