Skip to content

[refactor] client: consolidate compiled capability catalog #423

Description

@foxzool

Problem Statement

OpenLark 的编译能力目前由 Cargo feature、Client 字段与构造声明、registry 元数据、bootstrap cfg 列表和 FeatureLoader 分别描述。它们表达同一事实却没有 locality:bot 已经从 registry 目录漏掉,ai 的声明依赖与实际编译依赖不一致;registry interface 还宣称能返回 typed instance 和生命周期状态,但所有编译条目的 instance 都是 None。使用者无法把 Client::registry() 当成编译能力的可信来源,维护者新增业务域时必须跨多个 module 手工同步。

Solution

把编译可用性、Client 字段构造和诊断元数据合并到一个不可变的 compiled-capability catalog module。该 module 继续使用零成本的编译期生成,registry 保持纯元信息诊断用途;不存在的 typed-instance 和生命周期知识从 interface 删除,FeatureLoader 的重复入口被吸收。

User Stories

  1. As an OpenLark user, I want Client::registry() to report every compiled capability, so that diagnostics match the client I built.
  2. As an OpenLark user, I want disabled capabilities absent from the catalog, so that runtime reporting matches Cargo features.
  3. As an OpenLark bot user, I want the bot capability represented when compiled, so that diagnostics do not omit a usable client field.
  4. As an OpenLark AI user, I want reported dependencies to match actual feature dependencies, so that catalog information is trustworthy.
  5. As an OpenLark library user, I want metadata queries to succeed without implying runtime instances, so that the interface does not promise impossible behavior.
  6. As an OpenLark SDK maintainer, I want one declaration to generate client construction and metadata, so that new domains require one change.
  7. As an OpenLark SDK maintainer, I want compile-time generation preserved, so that no dynamic service locator or downcast cost is introduced.
  8. As an OpenLark test author, I want feature-matrix contract tests, so that catalog and Client fields cannot drift.
  9. As an OpenLark docs author, I want capability names and descriptions sourced from one catalog, so that documentation does not fork from runtime diagnostics.
  10. As an OpenLark operator, I want deterministic immutable metadata, so that diagnostics cannot expose meaningless lifecycle mutations.
  11. As an OpenLark maintainer, I want duplicate bootstrap paths removed, so that initialization has one implementation.
  12. As an OpenLark downstream user, I want existing metadata listing and presence checks preserved, so that useful diagnostic code remains compatible.

Implementation Decisions

  • A single immutable compiled-capability catalog is the source of truth for feature name, Client field construction, diagnostic name, description, dependencies, provided capabilities, and priority.
  • Macro generation remains compile-time and zero-cost; no runtime plugin container, Any downcast, or dynamic dispatch is introduced.
  • Client::registry() remains the external diagnostic seam.
  • Registry entries remain metadata-only. Typed-instance lookup, mutable lifecycle timestamps, and status transitions are removed from the public interface unless real instances and adapters exist.
  • The async FeatureLoader pass-through and duplicate bootstrap entry are removed or reduced to generated catalog consumption with no unused configuration argument.
  • Catalog dependencies must match Cargo feature relationships exactly; catalog presence must match Client field presence for every feature combination covered by CI.
  • Existing useful listing, lookup, has_service, description, dependency, capability, and priority behavior is retained through the smaller interface.
  • This deepens the macro-driven decision from the archived architecture audit; it does not reopen the rejected runtime service-container design.

Testing Decisions

  • The highest runtime test seam is Client::registry() on clients built under representative feature sets.
  • Compile-time feature-contract tests prove that each enabled Client field has exactly one catalog entry and each disabled feature has none.
  • Tests explicitly cover bot presence, AI dependency truth, duplicate-name rejection at generation time, stable ordering, and metadata completeness.
  • Tests assert public catalog results rather than generated macro internals, bootstrap helpers, or mutable registry state.
  • A no-default-features build and the full feature build are mandatory test modes; representative single-domain builds cover conditional generation.
  • Prior art is the repository's feature-contract tests and current registry listing examples, moved to the immutable catalog seam.

Out of Scope

Further Notes

  • Recommendation strength is Worth exploring because the catalog seam is useful, but the work must preserve the accepted metadata-only registry decision.
  • The deletion test proves FeatureLoader is shallow while the catalog earns its depth: deleting the catalog would spread capability truth back across every generated consumer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agenttype:refactor架构或接口收敛性重构

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions