diff --git a/.changeset/adr-0076-status-line-calibration.md b/.changeset/adr-0076-status-line-calibration.md new file mode 100644 index 0000000000..0f6a3c258c --- /dev/null +++ b/.changeset/adr-0076-status-line-calibration.md @@ -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 条目补一条状态注记(组合别名已不存在)。纯文档改动,不发布任何包。 diff --git a/docs/adr/0076-objectql-core-tiering.md b/docs/adr/0076-objectql-core-tiering.md index 0b6a5e4fbb..c66cc1ef06 100644 --- a/docs/adr/0076-objectql-core-tiering.md +++ b/docs/adr/0076-objectql-core-tiering.md @@ -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`). @@ -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**.