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
51 changes: 51 additions & 0 deletions .changeset/etl-pipeline-layer-retired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
"@objectstack/spec": major
---

refactor(spec)!: retire the L2 ETL layer — `automation/etl.zod.ts` had no executor, and the sync architecture doc was recommending it (#6414)

`ETLPipeline`, `ETLPipelineRun`, `ETLSource`, `ETLDestination`, `ETLTransformation`,
the `ETLEndpointType` / `ETLTransformationType` / `ETLSyncMode` / `ETLRunStatus`
enums and the `ETL` factory are REMOVED under ADR-0049 enforce-or-remove. The whole
file goes, on the same reading #4738 used to retire L1 `DataSyncConfig` one layer up:
**narrative-only**. No engine ever parsed, scheduled or executed an `ETLPipeline`.

Measured on `origin/main` immediately before the removal: the only non-spec
references in this repo are two fumadocs-generated documentation sources
(`apps/docs/.source/*.ts`), not executors; objectui has no reference at all; and
there is no `packages/spec/liveness/etl.json`, so no ADR-0049 gate ever had a reading
on the surface — while the same file family's EXECUTED half does have one
(`liveness/mapping.json`), which is what makes that absence meaningful rather than an
oversight.

FROM → TO, layer by layer — with one gap stated plainly instead of redirected:

| removed | use instead |
|---|---|
| `ETLPipeline.source` + `syncMode` + `schedule` (scheduled extraction from an external system) | `ConnectorSchema.syncConfig` (`integration/connector.zod.ts`) — the live, parsed sync surface: strategy, direction, cron schedule, `conflictResolution`, batching, delete mode |
| `ETLTransformation` of type `map` / `cast`-like per-field work | `mapping.fieldMapping[].transform` (`data/mapping.zod.ts`) — `none`/`constant`/`map`/`split`/`join`/`lookup`, applied row by row by the REST import path |
| `ETLPipeline.schedule` alone | `system/job.zod.ts` |
| `ETLTransformation` of type `join` / `aggregate` / `script` / `merge` / `deduplicate` / … | **nothing.** There is no replacement because there was never an implementation — those ten transformation types named capabilities no runtime had. Do the work where it runs (the destination warehouse's ELT, a `flow`, a scheduled job), and let multi-stage movement return through ADR-0049's ENFORCE route: the engine first, the vocabulary second |

**The fix:** delete the import. Nothing was ever deployed under an `ETLPipeline` —
that is the finding, not a consolation — so there is no data migration; `tsc` reports
TS2724/TS2305 at every import of a retired name.

**`packages/spec/docs/SYNC_ARCHITECTURE.md` is rewritten in the same change**, and
that is not incidental. It named `ETLPipeline` as the recommended destination for
authors displaced by the L1 retirement and tabulated ten transformation types with
copyable examples down to `script | Custom JavaScript/Python`. Retiring the schema
while the doc still recommended it would have been self-contradictory, and
forwarding L1's authors to a second layer with no executor was the defect compounding
rather than closing.

**Absorbed:** the #4962 `etl-retry-converged-onto-retry-policy` entry (`retry.maxAttempts`
→ `maxRetries`, default 3 → 0) — both land in the unreleased protocol 17, so composed,
a rename on a shape that does not survive the major has no observable effect, and its
`retiredKey()` tombstone goes with the shape that carried it.

The retirement kit — route 3: no tombstone, no D2 conversion.
`RETIRED_DEFS_BY_MAJOR[17]` (9 defs) plus the D3 `SemanticMigration`
`etl-pipeline-layer-retired` are the declaration.

<!-- adr-0087: registered etl-pipeline-layer-retired -->
52 changes: 52 additions & 0 deletions .changeset/http-server-runtime-vocabulary-retired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
"@objectstack/spec": major
---

refactor(spec)!: retire `system/http-server.zod.ts`'s runtime vocabulary — the event, capability and status shapes nothing ever emitted (#5295)

`ServerEventType`, `ServerEventSchema` / `ServerEvent`, `ServerCapabilitiesSchema` /
`ServerCapabilities` / `ServerCapabilitiesParsed` and `ServerStatusSchema` /
`ServerStatus` are REMOVED under ADR-0049 enforce-or-remove. This is the second and
final pass over the file: #4938 removed its CONFIG half (`HttpServerConfigSchema`,
nine keys, zero readers, zero authoring entry), and this removes the RUNTIME half —
a 7-member lifecycle event union, an eight-boolean capability report and a
five-state status record with connection and request counters. Nothing ever emitted,
consumed or parsed any of them.

FROM → TO:

| removed | what actually decides it |
|---|---|
| `ServerEventType` / `ServerEvent(Schema)` | nothing emits a server event feed. Lifecycle is the transport plugin's own start/stop seam; observability is `system/metrics.zod.ts` + `system/logging.zod.ts`, and `OS_SERVER_TIMING` for timings |
| `ServerCapabilities(Schema/Parsed)` | a transport plugin declares what it provides by implementing the kernel plugin contract — the seams it registers ARE the capability statement |
| `ServerStatus(Schema)` | `/health` for liveness, the metrics surface for counters |

**The fix:** delete the import. There is no replacement key, because there was
never a key — none of the four was authorable on any shape. Server-level
configuration that IS authorable is untouched: `defineStack({ server: { trustProxy,
security } })` / `StackServerConfigSchema` (#5006) parses exactly as it did in 16.x,
as does the route-registration half of the same module (`RouteHandlerMetadata`,
`MiddlewareType`, `MiddlewareConfig`).

**Why now, and what unblocked it.** The card was held rather than queued on a real
doubt: a response/capability vocabulary can legitimately be a REFERENCE surface for
host implementers, so "zero consumers in this repo" is weaker evidence for one of
those than for an authorable key. It was lifted by measuring the reference reader
itself — `plugin-hono-server`, the one in-tree host implementation, neither
implements nor reports any of the three: it names no capability record, no status
shape and no event union, and what it registers is routes and middleware. The
control passed in the same sweep (`MiddlewareConfig`, twelve lines away, resolves to
`packages/runtime/src/middleware.ts`).

The retirement kit — route 3 of the retirement playbook, as #4938 was in this same
file: **no `retiredKey()` tombstone and no D2 conversion**, because a prescription
nobody can receive is noise and there is no authored document to rewrite.
`RETIRED_DEFS_BY_MAJOR[17]` (4 defs) plus the D3 `SemanticMigration`
`http-server-runtime-vocabulary-retired` are the declaration; the generated
baselines (`json-schema.manifest/system.json`, `authorable-surface/system.json`,
`api-surface/system.json`) lose their entries in the same change, deliberately.

If host-implementer conformance becomes a real requirement it returns through the
ENFORCE route: an adapter contract with a checker behind it, vocabulary second.

<!-- adr-0087: registered http-server-runtime-vocabulary-retired -->
55 changes: 55 additions & 0 deletions .changeset/view-management-protocol-retired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
"@objectstack/spec": major
"@objectstack/client": major
---

refactor(spec,client)!: retire `ViewProtocol`'s five viewId-addressed methods and their ten schemas (#6239)

`listViews`, `getView`, `createView`, `updateView` and `deleteView` — the
`ViewProtocol` interface and `ListViews`/`GetView`/`CreateView`/`UpdateView`/`DeleteView`
Request+Response schemas in `api/protocol.zod.ts` — are REMOVED under ADR-0049
enforce-or-remove (maintainer ruling 2026-08-07). `@objectstack/client` drops the
five response types it re-exported.

Measured on `origin/main` immediately before the removal, the surface had none of
the three things a protocol method needs:

- **no implementation** — `packages/metadata-protocol/src/protocol.ts` declares no
`listViews`/`getView`/`createView`/`updateView`/`deleteView`; its only view
resolver is `getUiView`;
- **no route** — `packages/rest/src/rest-server.ts` never mentions `viewId`, so
nothing viewId-addressed was reachable over HTTP at all;
- **no caller** — the only `ViewProtocol` mention outside its own file was
`content/docs/kernel/services-checklist.mdx`, which already recorded the five as
declared-and-unrouted.

FROM → TO — both replacements are surfaces that were always the live ones:

| removed | use instead |
|---|---|
| `listViews` / `getView` / `createView` / `updateView` / `deleteView` (+ their 10 schemas) | the generic metadata methods with `type: 'view'` — `getMetaItem` / `getMetaItems` / `saveMetaItem` / `deleteMetaItem`, served at `/api/v1/meta/view/:name` |
| `GetViewResponse` as "the shape of the resolved view" | `GetUiViewResponse` — `getUiView`, served at `GET /api/v1/ui/view/:object/:type` |

**The fix:** delete the import and address views by NAME through the metadata API
(`view` is a metadata type), or by object+type through `getUiView`. Nothing
addressed a view by `viewId` before this change either; that is the finding.

**Why a removal rather than a note.** The declared surface is name-identical and
semantics-adjacent to a real one, which makes it an attractive nuisance in every
grep — and it has already mis-directed a decision: **#5948's issue body AND its
2026-08-07 maintainer ruling both read `GetViewResponseSchema` (zero
implementations) as the contract of `GET /ui/view/:object/:type`**, whose declared
response is `GetUiViewResponseSchema`, 250 lines up and one word different. That
ruling's reasoning happened to survive the mix-up; this removal stops relying on
that luck.

The retirement kit — route 3: **no tombstone and no D2 conversion** (none of the ten
was a key on an authorable shape, and nothing parsed them, so there is no source or
`sys_metadata` row to rewrite). `RETIRED_DEFS_BY_MAJOR[17]` (10 defs) plus the D3
`SemanticMigration` `view-management-protocol-retired` are the declaration; the
generated baselines and reference docs lose their entries in the same change.

If "read and write ONE view by id" becomes a real requirement, it returns
implementation-first.

<!-- adr-0087: registered view-management-protocol-retired -->
3 changes: 1 addition & 2 deletions content/docs/getting-started/quick-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ REST/GraphQL endpoints, real-time subscriptions, and discovery.
| **[Metadata](/docs/references/api/metadata)** | `metadata.zod.ts` | Metadata | API metadata endpoints |
| **[Storage](/docs/references/api/storage)** | `storage.zod.ts` | Storage | API storage operations |

## Automation Protocol (5 schemas)
## Automation Protocol (4 schemas)

Flows, state machines, approvals, and integrations.

Expand All @@ -155,7 +155,6 @@ Flows, state machines, approvals, and integrations.
| **[Approval](/docs/references/automation/approval)** | `approval.zod.ts` | ApprovalNodeConfig | Flow approval-node config |
| **[State Machine](/docs/references/automation/state-machine)** | `state-machine.zod.ts` | StateMachine | State machine definitions |
| **[Webhook](/docs/references/automation/webhook)** | `webhook.zod.ts` | Webhook | Outbound webhooks |
| **[ETL](/docs/references/automation/etl)** | `etl.zod.ts` | ETLPipeline | Data transformation pipelines |

## Security Protocol (3 schemas)

Expand Down
32 changes: 22 additions & 10 deletions content/docs/kernel/services-checklist.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -320,22 +320,34 @@ registered under their own names (`security.permissions`, `security.rls`,

## 5–6. Business Services

### 5. ui Service — 5 declared methods, none routed
`listViews`, `getView`, `createView`, `updateView`, `deleteView`
### 5. ui Service — 1 routed method ✅ (was 5 declared, none routed)
`getUiView`

<Callout type="warn">
These five are **optional members of `ViewProtocol` that nothing implements and no
route reaches** — `view` is a metadata type, so view CRUD goes through the metadata
API (`/api/v1/meta`), not through them. Nothing anywhere registers the `ui` slot
either (#4093 / #4146), so `CORE_SERVICE_PROVIDER.ui` names
`@objectstack/metadata-protocol` rather than a `ui` plugin: the one route the `/ui`
domain serves is `GET /api/v1/ui/view/:object[/:type]`, which calls `getUiView` on
the **`protocol`** service that `assembleMetadataProtocol()` registers (invoked by
Nothing anywhere registers the `ui` slot (#4093 / #4146), so `CORE_SERVICE_PROVIDER.ui`
names `@objectstack/metadata-protocol` rather than a `ui` plugin: the one route the
`/ui` domain serves is `GET /api/v1/ui/view/:object[/:type]`, which calls `getUiView`
on the **`protocol`** service that `assembleMetadataProtocol()` registers (invoked by
`ObjectQLPlugin`, or by the standalone `createMetadataProtocolPlugin()`). Without it
the domain answers **501** with that remedy spelled out, not a generic "install a ui
plugin".
</Callout>

#### Retired in v17: `ViewProtocol`'s five methods
`listViews`, `getView`, `createView`, `updateView`, `deleteView` — and their ten
Request/Response schemas — were removed in
[#6239](https://github.com/objectstack-ai/objectstack/issues/6239) under ADR-0049
enforce-or-remove. This checklist had recorded them as declared-and-unrouted since it
was written; the removal makes that reading permanent instead of re-derivable. Views
are read and written through the surfaces that always served them: the metadata API
(`/api/v1/meta/view/:name`, `view` being a metadata type) for the stored definition,
and `getUiView` above for the resolved render-time view.

The concrete cost of leaving it declared is on the record: **#5948's issue body and its
2026-08-07 maintainer ruling both read `GetViewResponseSchema` — this retired block,
zero implementations — as the contract of `GET /ui/view/:object/:type`**, whose declared
response is `GetUiViewResponseSchema`. One word apart, and identical to a grep.

### Retired in v17: the `workflow` slot
The slot, its `IWorkflowService` contract and the three `WorkflowProtocol`
methods (`getWorkflowConfig`, `getWorkflowState`, `workflowTransition`) were
Expand Down Expand Up @@ -509,7 +521,7 @@ a package that cannot be installed is a dead end, which is why

| Slot | State |
|:-------|:------------|
| **ui** | Nothing registers the slot. `ViewProtocol`'s five methods are declared and unrouted; view CRUD runs through `/api/v1/meta`, and `/api/v1/ui/view/:object` is served by the `protocol` service. |
| **ui** | Nothing registers the slot. `ViewProtocol`'s five declared-and-unrouted methods were **retired in v17** (#6239); view CRUD runs through `/api/v1/meta`, and `/api/v1/ui/view/:object` is served by the `protocol` service. |
| **search** | Nothing ships. Contract and engine enum exist in `@objectstack/spec` only. |
| **ai** | Nothing in this repo — `service-ai` (chat, completion, models, conversations) is Cloud/EE. |
| **realtime transport** | The service exists but no WebSocket/SSE route is mounted, so `routes.realtime` is deliberately never advertised. |
Expand Down
Loading
Loading