Skip to content

Commit c546d7f

Browse files
os-zhuangclaude
andauthored
docs(adr): ADR-0076 rev.6 — D10: "protocol" is a contract, not an impl package; distribute impls to domain packages (#2427)
Extends the kernel review. Verified the central ObjectStackProtocolImplementation facade is the wrong end-state: it implements only 4/11 contract domains; analytics is duplicated and collides (both ObjectQLPlugin and AnalyticsServicePlugin register a 'analytics' service — a ~66-line facade copy vs service-analytics's ~1.8k-LOC engine); feed is already delegated; the domain services already exist. D10: reserve "protocol" for the contract (spec/api only, no *-protocol impl package); DataProtocol → transport, MetadataProtocol → a metadata-domain package (rename metadata-protocol → metadata-runtime), analytics/feed/realtime → their existing services (drop the facade's duplicates); dispatcher routes per slice. Refines D1 (metadata-protocol = intermediate) and completes D9. Cross-repo window. Docs only; empty changeset. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent de01520 commit c546d7f

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

.changeset/adr-0076-rev6.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
docs(adr): ADR-0076 rev.6 — D10 (protocol=contract, distribute impls). Docs only.

docs/adr/0076-objectql-core-tiering.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ADR-0076: objectql is the data engine — relocate metadata management (protocol) out of it; enforce the boundary; defer the engine repo-split
22

3-
**Status**: Proposed (2026-06-28, rev. 5adds the kernel-architecture review: the engine is a clean primitive; the real debt is the `ObjectStackProtocol` god-interface, segmented per ISP in D8–D9) — v12 assessment
3+
**Status**: Proposed (2026-06-28, rev. 6 — kernel review extended: D10 reserves "protocol" for the contract and distributes implementations to domain packages; the central facade / `*-protocol` impl package is a transitional intermediate) — v12 assessment
44
**Deciders**: ObjectStack Protocol Architects
55
**Builds on**: [ADR-0005](./0005-metadata-customization-overlay.md) (sys_metadata overlay substrate), [ADR-0025](./0025-plugin-package-distribution.md) (plugin package distribution), [ADR-0033](./0033-ai-assisted-metadata-authoring.md) (open-core boundary), [ADR-0048](./0048-cross-package-metadata-collision.md) (package id is the addressing unit), [ADR-0066](./0066-unified-authorization-model.md) (secure-by-default, posture-gated bypass)
66
**Consumers**: **new** `@objectstack/metadata-protocol` (receives `protocol` + `sys-metadata-repository` + `metadata-diagnostics`), `@objectstack/objectql` (loses protocol → becomes a lean data engine; keeps a back-compat re-export), `@objectstack/metadata-core` (gains the `SysMetadataEngine` interface), `@objectstack/plugin-security`, `@objectstack/plugin-sharing`, `@objectstack/spec`, and out-of-tree embedders — notably `../objectbase` (its `gateway`).
@@ -52,6 +52,9 @@ engine surface protocol needs: SysMetadataEngine = { find, findOne, insert, upda
5252
- `@objectstack/objectql` re-exports `ObjectStackProtocolImplementation` from the new package for back-compat (the only two source importers — `plugin.ts`, `index.ts` — are updated; `plugin.ts` keeps wiring it, now imported from `metadata-protocol`).
5353
- Result: objectql is a lean data engine **by construction** — 268KB of metadata logic physically leaves the engine package. The gateway depends on `@objectstack/objectql` and never pulls protocol. (This **replaces** the rev.3 `./core` subpath proposal, which was a workaround for the false premise that protocol must stay in objectql. A subpath remains an optional later polish to also exclude the small `ObjectQLPlugin`/`kernel-factory` glue.)
5454

55+
56+
> **Refined by D10** — this `@objectstack/metadata-protocol` *implementation* package is a pragmatic **intermediate** (it got protocol out of the engine, unblocking the lean gateway). It is **not** the end-state: D10 reserves the name "protocol" for the contract and distributes implementations to their domain packages.
57+
5558
### D2 — Boundary ratchet keeps the engine pure [new — keystone]
5659

5760
A CI test asserts `@objectstack/objectql` does **not** import `@objectstack/metadata-protocol` / `plugin` / `kernel` (the dependency points one way: `metadata-protocol → objectql-public-interface`, never back). This makes the relocation durable and creates backpressure against the engine re-absorbing metadata/platform concerns — the root cause of the original complexity. Fits the team's existing ratchet culture (liveness / api-surface / authz-matrix).
@@ -92,6 +95,23 @@ Decision — split the interface into focused contracts:
9295

9396
The segmentation is **spec/type-level and may start incrementally now** (define sub-interfaces; narrow consumers over time). The implementation restructure + the `@objectstack/metadata-protocol` rename are breaking and ride the **same cross-repo window as D7 / Step 2**.
9497

98+
### D10 — "protocol" is a contract, not an implementation package; distribute impls to domain packages [new — kernel review]
99+
100+
A single `ObjectStackProtocolImplementation` facade — and any `*-protocol` *implementation* package — is the wrong end-state. Verified against source:
101+
- The facade implements only **4 of the 11** contract domains (data, metadata, analytics, feed). The other 7 (realtime / notifications / workflow / ai / i18n / views / permissions) are **not implemented in it** — they belong to their own services or aren't implemented at all.
102+
- **Analytics is duplicated and collides**: both `ObjectQLPlugin` (`objectql/src/plugin.ts`) and `AnalyticsServicePlugin` (`@objectstack/service-analytics`) register a service named `'analytics'` — the facade's ~66-line `analyticsQuery` versus service-analytics's ~1.8k-LOC engine (three strategies incl. native-SQL). Last-registered wins; the facade's copy is a strictly lesser duplicate.
103+
- **Feed is already delegated** to `IFeedService`; the facade only forwards.
104+
- The domain service packages already exist: `service-analytics`, `service-messaging`, `service-realtime`.
105+
106+
Target end-state:
107+
- **"protocol" names ONLY the contract** — the segmented interfaces in `@objectstack/spec/api` (D9). There is **no `*-protocol` implementation package**.
108+
- **`DataProtocol`** impl → engine-adjacent / transport (thin wire-normalizers).
109+
- **`MetadataProtocol`** impl → a metadata-**domain** package; rename `@objectstack/metadata-protocol` → e.g. `@objectstack/metadata-runtime` (it owns `sys_metadata` — a legitimate business domain, not "protocol").
110+
- **Analytics / Feed / Realtime / Notification / …** → their existing service packages; **delete the facade's duplicated `analyticsQuery` + feed wrappers** and the `ObjectQLPlugin` `'analytics'` adapter (let `service-analytics` own the `'analytics'` service).
111+
- **The transport/dispatcher routes each contract-slice to the owning service** (it already resolves services by name) — no central facade class.
112+
113+
This **refines D1** (the `metadata-protocol` package was an intermediate, not the end-state) and **completes D9**. Executed at the cross-repo window with D7 / Step 2.
114+
95115
## Feasibility (verified against current source)
96116

97117
| Claim | Status | Evidence |

0 commit comments

Comments
 (0)