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
4 changes: 4 additions & 0 deletions .changeset/adr-0076-status-line-calibration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

docs(adr-0076): 把状态行从 `Proposed` 校准为 `Accepted`,并逐条记录 D1–D12 的真实落地状态(#5063)。参照 #4919 对 ADR-0078 的做法:不整体翻牌,每条决定给出在 `origin/main` 上核对到的证据 —— D3 完全未建、D10/D11 只落一半、D9 已越过 step-1 把联合类型彻底解散、D7 已有 CI 触发指标。同时给 D9 的 back-compat 条目补一条状态注记(组合别名已不存在)。纯文档改动,不发布任何包。
16 changes: 14 additions & 2 deletions docs/adr/0076-objectql-core-tiering.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# ADR-0076: objectql is the data engine — relocate metadata management (protocol) out of it; enforce the boundary; defer the engine repo-split

**Status**: Proposed (2026-06-28, rev. 9) — D1–D12 below. D9 step-1 (interface segmentation) shipped in #2429; OQ#7 resolved (keep `metadata-protocol` name). rev.9 adds **D12 (honest capabilities** — discovery must not report stub/fallback services as real; the analytics fallback + dev stubs are marked honestly, not deleted) and corrects the D10 analytics note (deliberate fallback + `replaceService`, not a collision). — v12 assessment. Verified 2026-07-16: D1 (metadata-protocol extraction + back-compat re-export), D2 (core-boundary ratchet test), D9-step1 (segmented protocol interfaces) confirmed in code; D3 capability/profile contract unbuilt; D12 framework side landed in #3028 (standardized `__serviceInfo` marker — OQ#11 — honored by BOTH discovery builders; `svcAvailable` no longer hardcodes `available`; analytics fallback reports `degraded`, `/realtime` no longer advertised) — the console-side consumer update ("trust only `handlerReady:true`") remains for the cross-repo window; D7/D10/D11-decomposition deferred as designed (OQ#9/OQ#10 resolved below, #3037).
**Status**: Accepted — D1/D2/D4/D5/D6/D8/D9 implemented; D10/D11/D12 partially landed; D3 unbuilt; D7 deliberately deferred (proposed 2026-06-28, rev. 9 · calibrated 2026-08-05 by #5063). This ADR has been binding for some time — `AGENTS.md`, `packages/runtime/src/domains/*` (D11's own output), `packages/objectql`'s core boundary and ADR-0121 all cite it as a settled decision — while the header still read `Proposed`; per Prime Directive #13 an accepted decision binds until superseded, so the header is corrected here and, following #4919's calibration of ADR-0078, **per decision** rather than by a single flip. Verified against source (not against the rev.9 narrative), 2026-08-05:

- **D1 — implemented, with OQ#2 unexecuted.** `packages/metadata-protocol/` owns `protocol.ts`, `sys-metadata-repository.ts` and `metadata-diagnostics.ts`; `packages/objectql` depends on it one-way (`packages/objectql/package.json`, `src/plugin.ts` imports `assembleMetadataProtocol`). **But `SysMetadataEngine` never moved to `@objectstack/metadata-core`** — it is still declared in `packages/metadata-protocol/src/sys-metadata-repository.ts` and `packages/metadata-core/src/` has no occurrence of the name. OQ#2 is therefore *unexecuted*, not resolved; the D1 bullet below states the intent, not the state.
- **D2 — implemented.** `packages/objectql/src/core-boundary.ratchet.test.ts` walks the `core.ts` import closure and forbids `@objectstack/metadata-protocol` plus the local `plugin` / `kernel-factory` modules.
- **D3 — unbuilt. The one decision here with no implementation at all.** No `profile: 'trusted' | 'internal'` exists in `packages/objectql/src`, `packages/core/src` or `packages/spec/src/kernel`; nothing derives required capabilities from object declarations; boot is **not** fail-closed — `packages/core/src/kernel.ts` only *warns* ("System started with degraded capabilities. Missing core services: …"). The `requiredCapabilities` / `provides` keys that do exist belong to the unrelated plugin-conformance schema `packages/spec/src/kernel/plugin-capability.zod.ts`, not to this decision. (Zero-hit counter-checked against live neighbours in the same search surface: `registerMiddleware`, `isServiceServeable`, `__serviceInfo` all match.)
- **D4/D5/D6/D8 — ratifications, all still true.** `@objectstack/formula` remains an `objectql` dependency used by `engine.ts` / `hook-wrappers.ts` / `validation/rule-validator.ts` (D4). `@objectstack/spec` carries only `zod` as a runtime dependency, and `examples/embed-objectql/` boots `@objectstack/objectql/core` against an ordinary `ObjectSchema.create` object — the same definition shape a full backend ships (D5, and Phasing P4). `engine.ts`'s `registerMiddleware` is the attachment point `plugin-security` and `plugin-sharing` actually use (D6), and the engine still hard-codes no governance (D8) — the D2 ratchet is what keeps it that way.
- **D9 — implemented, past step-1, at its own rev.7 end-state.** `packages/spec/src/api/protocol.zod.ts` declares ten per-domain contracts (`DataProtocol`, `MetadataProtocol`, `AnalyticsProtocol`, `AutomationProtocol`, `PackageProtocol`, `ViewProtocol`, `PermissionProtocol`, `RealtimeProtocol`, `NotificationProtocol`, `I18nProtocol`), and **no `ObjectStackProtocol` union type is declared or exported anywhere in the repo** — the transitional composed alias is *dissolved*, not merely deprecated. Consumers are narrowing accordingly: `packages/rest/src/rest-server.ts` types its dependency as `RestProtocol = DataProtocol & MetadataProtocol`.
- **D10 — partially implemented.** Landed: the feed domain and then the analytics fallback left the facade (analytics now has exactly one implementation, in `service-analytics`), and OQ#7 resolved to keep the package name. Outstanding: the central facade class this decision rules out **still exists** — `packages/metadata-protocol/src/protocol.ts` declares `class ObjectStackProtocolImplementation implements DataProtocol, MetadataProtocol, PackageProtocol` — so the `DataProtocol` implementation has not moved to the engine-adjacent/transport layer and **OQ#6 remains open**.
- **D11 — substantially implemented; the rest-server half is untouched.** The dispatcher decomposed exactly as OQ#9's verdict describes: every domain body lives in `packages/runtime/src/domains/*`, routing goes through `packages/runtime/src/domain-handler-registry.ts`'s `DomainHandlerRegistry`, and `http-dispatcher.ts` is down to ~1.7k LOC from the ~3.8k recorded below. Multi-adapter is validated (OQ#10) by `packages/qa/http-conformance`. **Not** decomposed: the *second* central route generator this decision names — `packages/rest/src/rest-server.ts` — is now ~7.7k LOC, i.e. larger than the ~5.1k figure below, not smaller.
- **D12 — framework side implemented; console side cross-repo and unverified from here.** `packages/spec/src/api/discovery.zod.ts` carries the `unavailable` / `degraded` / `stub` statuses plus `ServiceSelfInfoSchema` + `readServiceSelfInfo`; `svcAvailable` in `packages/runtime/src/http-dispatcher.ts` derives `status`/`handlerReady` from that marker for every slot (no hardcodes left); `packages/runtime/src/service-serveable.ts`'s `isServiceServeable` is the single predicate the dispatcher-owned domains, the route-mount gate and discovery all read. The consumer half ("trust only `handlerReady: true`") lives in cloud/objectui and cannot be confirmed from this repo.
- **D7 — deferred as designed, and now instrumented.** `packages/objectql` is still in the monorepo. New since rev.9: `scripts/check-engine-split-ratio.mjs` and `.github/workflows/engine-split-metric.yml` compute and report the cross-package commit ratio that gates the split; it is deliberately **report-only** because the threshold itself is still OQ#5.

This supersedes the 2026-07-16 verification note, which predates D9's dissolution of the union, D11's decomposition and D12's later passes.
**Deciders**: ObjectStack Protocol Architects
**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)
**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`).
Expand Down Expand Up @@ -94,7 +106,7 @@ Decision — split the interface into focused contracts:
- **`DataProtocol`** — `findData/getData/createData/updateData/deleteData` (+ batch): thin wire-normalizers over the engine.
- **`MetadataProtocol`** — metadata read/write, draft/publish, locks (ADR-0010), commits (ADR-0067), package ownership (ADR-0048), `loadMetaFromDb`: the heavy control plane (the true content of `@objectstack/metadata-protocol`).
- **Optional capability protocols** — `AnalyticsProtocol` / `FeedProtocol` / `RealtimeProtocol` / `NotificationProtocol` / `ViewProtocol` / …, each owned by its existing service and independently optional/versionable.
- **Back-compat** — keep `ObjectStackProtocol = DataProtocol & MetadataProtocol & Partial<…>` as a composed alias so current callers/types keep working.
- **Back-compat** — keep `ObjectStackProtocol = DataProtocol & MetadataProtocol & Partial<…>` as a composed alias so current callers/types keep working. *(Status 2026-08-05 (#5063): the alias is **gone**, not merely deprecated — no `ObjectStackProtocol` type is declared or exported anywhere in `packages/`, only prose references to the historical name remain. The rev.7 refinement immediately below is therefore the state, not the plan; consumers already depend on the narrow slices, e.g. `rest-server.ts`'s `RestProtocol = DataProtocol & MetadataProtocol`.)*

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**.

Expand Down
Loading