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
89 changes: 89 additions & 0 deletions .changeset/16059-startup-orchestrator-shipped-shape.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
"@objectstack/spec": minor
"@objectstack/core": minor
---

feat(spec,core)!: the startup contract describes what the kernel produces — the orchestrator vocabulary is retired and `PluginStartupResult` is declared once (#16059)

<!-- adr-0087: registered startup-orchestrator-retired -->

**BREAKING** — a published exported surface is removed, landing in the launch window as
`minor` (the lockstep convention: `major` is refused by `check-changeset-no-major`, and
breaking-ness is carried by this banner plus the ADR-0087 disposition above).

`@objectstack/spec` declared a plugin startup ORCHESTRATOR that was never built, and its
one shape that *is* real had drifted away from the kernel that produces it. The maintainer
ruling on this card keeps a startup-result contract, and makes it describe what the kernel
actually returns.

## What is removed

`IStartupOrchestrator` (`orchestrateStartup` / `rollback` / `checkHealth` /
`startWithTimeout`) and the three schemas it tied together. Nothing in any repository
implemented the interface and nothing parsed the schemas; `healthCheck` and `HealthStatus`
named a per-plugin startup health probe the runtime has never had.

| removed | from | what to write instead |
|:--|:--|:--|
| `IStartupOrchestrator` | `@objectstack/spec/contracts` | nothing — plugin startup is the kernel's own boot loop |
| `StartupOptionsSchema` / `StartupOptions` / `StartupOptionsParsed` | `@objectstack/spec/kernel`, `/contracts` | `startupTimeout` on the plugin; `rollbackOnFailure` on the kernel config |
| `StartupOptions.healthCheck` | (with the schema) | **no replacement** — no startup probe system exists |
| `HealthStatusSchema` / `HealthStatus` | `@objectstack/spec/kernel`, `/contracts` | **no replacement** — see above |
| `StartupOrchestrationResultSchema` / `StartupOrchestrationResult` | `@objectstack/spec/kernel` | `ObjectKernel.getPluginStartupDurations()` |

`StartupOptions.parallel` and `StartupOptions.context` have no replacement either: the
kernel starts plugins sequentially and passes its own `PluginContext`.

## What survives, re-declared

`PluginStartupResultSchema` / `PluginStartupResult` stay on both entries, rewritten to the
shape `@objectstack/core` has always returned from `ObjectKernel.startPluginWithTimeout()`.
`@objectstack/core` now **imports** that type instead of declaring a twin, so the two
cannot drift again.

| member | before (spec) | after (spec and core, one declaration) |
|:--|:--|:--|
| `plugin: { name, version? }` | required | **removed** — write `pluginName: string` |
| `pluginName` | absent | `string`, required |
| `success` | `boolean`, required | unchanged |
| `durationMs` | `number`, **required** | `number`, **optional** (absent when the plugin declares no `start()`) |
| `startTime` | absent (it was core's own deprecated alias) | **removed** — read `durationMs`, which always carried the same value |
| `error` | serializable projection | unchanged (a thrown `Error` satisfies it) |
| `timedOut` | absent | `boolean`, optional — set when the failure was the timeout |
| `health: HealthStatus` | optional | **removed** — no probe ever filled it |

**The one-line fix:** rename `plugin: { name }` to `pluginName`, delete `health`, and read
`durationMs` wherever you read `startTime`. All three old spellings are `retiredKey()`
tombstones on the surviving schema, so each is a `tsc` error at the construction site and a
parse error carrying the prescription.

`startTime` is the one member whose removal a reader can OBSERVE: `@objectstack/core`
populated it beside `durationMs` with the identical elapsed value, under its own ADR-0087
L1 deprecation, and `ObjectKernel.startPluginWithTimeout()` stops setting it here. Mirroring
it on the contract was the alternative and the tree refuses it — `check:duration-unit-keys`
(ruling B on #14478) fails an elapsed number whose key name carries no unit, and neither of
that rule's two schema-declared exemptions fits: it is not an `EpochMs` instant and it
mirrors no external standard. Renaming it to `startTimeMs` would mint a spelling nothing has
ever produced, for a member already documented as slated for removal.

For `@objectstack/core` consumers the members are unchanged; the one narrowing is that
`PluginStartupResult.error` is now typed as the serializable projection
(`name` / `message` / `stack?` / `code?`) rather than `Error`. The kernel still puts the
thrown instance there, so `result.error instanceof Error` still narrows — only code that
reads an `Error`-only member such as `cause` off it without that guard needs the guard.

## The retirement kit

Route 3 of the `spec-property-retirement` playbook: no authored document carried any of
the three defs, so there is no seam for a D2 conversion and no author to hand a tombstone
to. `RETIRED_DEFS_BY_MAJOR[18]` (`kernel/StartupOptions`, `kernel/HealthStatus`,
`kernel/StartupOrchestrationResult`) plus the D3 semantic entry
`startup-orchestrator-retired` **are** the declaration, and the three
`json-schema.manifest/kernel.json` keys plus their 16 `authorable-surface/kernel.json`
lines are deleted deliberately in this same change. The two keys of the SURVIVING result
schema (`plugin`, `health`) take the tombstone route instead, registered in
`RETIRED_KEYS_BY_MAJOR[18]`, because that def keeps emitting and its type is imported by
`@objectstack/core`.

Runtime behaviour is deliberately unchanged: nothing ever read the retired surfaces, and
the kernel boot loop is untouched.
2 changes: 1 addition & 1 deletion content/docs/getting-started/quick-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Plugin architecture, manifests, and kernel runtime.
| **[Plugin Validator](/docs/references/kernel/plugin-validator)** | `plugin-validator.zod.ts` | ValidationResult, PluginMetadata | Plugin validation |
| **[Plugin Versioning](/docs/references/kernel/plugin-versioning)** | `plugin-versioning.zod.ts` | PluginCompatibilityMatrix, DeprecationNotice | Version compatibility |
| **[Service Registry](/docs/references/kernel/service-registry)** | `service-registry.zod.ts` | ServiceRegistryConfig, ServiceMetadata | Service discovery |
| **[Startup Orchestrator](/docs/references/kernel/startup-orchestrator)** | `startup-orchestrator.zod.ts` | StartupOptions, StartupOrchestrationResult | System startup |
| **[Startup Orchestrator](/docs/references/kernel/startup-orchestrator)** | `startup-orchestrator.zod.ts` | PluginStartupResult | The per-plugin result the kernel returns for every plugin it starts |
| **[Events](/docs/kernel/events)** ↗ | `events.zod.ts` | Event, EventBusConfig | System event bus — the hand-written guide, outside `references/kernel/` (which splits the same surface across six `events-*` pages) |
| **[Metadata Loader](/docs/references/kernel/metadata-loader)** | `metadata-loader.zod.ts` | MetadataLoaderContract | Metadata loading |
| **[Package Registry](/docs/references/kernel/package-registry)** | `package-registry.zod.ts` | InstalledPackage, InstallPackageRequest | Package resolution |
Expand Down
10 changes: 5 additions & 5 deletions content/docs/references/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Protocol Reference
description: Every schema published by @objectstack/spec — 1525 schemas across 14 protocol modules
description: Every schema published by @objectstack/spec — 1522 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 @@ -25,15 +25,15 @@ counts are sums of the rows they head. Regenerate with
| [Data Protocol](/docs/references/data) | 29 | 173 | 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 | 24 | The single connector protocol (ADR-0097) — catalog descriptors and provider-bound instances. |
| [Kernel Protocol](/docs/references/kernel) | 30 | 162 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
| [Kernel Protocol](/docs/references/kernel) | 30 | 159 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
| [Marketplace Protocol](/docs/references/marketplace) | 4 | 30 | The package & marketplace format — package identity and versions, listing, publish, review, search, install, template manifests. |
| [QA Protocol](/docs/references/qa) | 1 | 8 | Declarative test suites — scenarios, steps, actions and assertions. |
| [Security Protocol](/docs/references/security) | 5 | 30 | Permission sets, row-level security, sharing rules, tenancy posture. |
| [Shared Protocol](/docs/references/shared) | 10 | 31 | 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) | 33 | 272 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
| [UI Protocol](/docs/references/ui) | 16 | 153 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
| **Total** | **193** | **1525** | 14 protocol modules |
| **Total** | **193** | **1522** | 14 protocol modules |

---

Expand Down Expand Up @@ -196,7 +196,7 @@ The single connector protocol (ADR-0097) — catalog descriptors and provider-bo

## Kernel Protocol

**Source:** `packages/spec/src/kernel/` · **Import:** `@objectstack/spec/kernel` · **30 pages, 162 schemas**
**Source:** `packages/spec/src/kernel/` · **Import:** `@objectstack/spec/kernel` · **30 pages, 159 schemas**

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

Expand Down Expand Up @@ -231,7 +231,7 @@ Plugin lifecycle and manifests, capabilities and security, metadata loading, ser
| [`plugin-validator.zod.ts`](/docs/references/kernel/plugin-validator) | `PluginMetadata`, `ValidationError`, `ValidationResult`, `ValidationWarning` |
| [`plugin-versioning.zod.ts`](/docs/references/kernel/plugin-versioning) | `BreakingChange`, `CompatibilityLevel`, `CompatibilityMatrixEntry`, `DependencyConflict`, `DeprecationNotice`, `MultiVersionSupport`, `PluginCompatibilityMatrix`, `PluginDependencyResolutionResult`, `PluginVersionMetadata`, `SemanticVersion`, `VersionConstraint` |
| [`service-registry.zod.ts`](/docs/references/kernel/service-registry) | `ScopeConfig`, `ScopeInfo`, `ServiceFactoryRegistration`, `ServiceMetadata`, `ServiceRegistryConfig`, `ServiceScopeType` |
| [`startup-orchestrator.zod.ts`](/docs/references/kernel/startup-orchestrator) | `HealthStatus`, `PluginStartupResult`, `StartupOptions`, `StartupOrchestrationResult` |
| [`startup-orchestrator.zod.ts`](/docs/references/kernel/startup-orchestrator) | `PluginStartupResult` |

---

Expand Down
Loading
Loading