25 KiB
DWS Agent Schema 统一方案
1. 核心定义
DWS Schema 是当前二进制公开 CLI 的版本化 Agent 执行契约。它描述真实 Cobra 命令,并补充 Agent 选择、参数映射、组合约束、安全确认和接口事实。
设计遵循三条硬规则:
- Schema 描述 CLI,不制造 CLI。
CommandRegistry、ProductDecl / leafContract、metadata 和 Catalog 都不能凭空创建 Cobra 命令或 flag;registry 中的每个路径都必须精确绑定真实 runnable Cobra leaf。interface 事实由 leafContract/ParamDecl声明(schema_mcp_metadata已退役),不得从 MCP meta 生成 CLI flag(见 §4.1 同源决策)。 - 所有来源只解析一次。 来源经过统一 resolver 进入 typed
SchemaRegistry,所有查询、导出和门禁都消费同一个SchemaRegistry/SchemaIndex。 - Collector-first,Catalog 只出不进。 identity collector(
CollectIdentitySpecs,遍历携带ContractFinal.Identity的 live Cobra leaves)是稳定 command identity/navigation 的唯一事实源;reviewedschema_command_registry/已退役,identity 由声明(Contract)即代码提供,不再有独立的 reviewed identity 文件。production 通过RegisterSchemaSourceRoot→ResolveSchemaBuild组装SchemaRegistry,并从它投影 ToolSpec wire 与ResolveMeta。cmd_schema_catalog只能生成 CI/local dump,internal/cli/schema_catalog/、schema_meta_index.gob和schema_meta_index.json不得提交或成为运行时来源。schema_agent_metadata//schema_hints//schema_command_registry/已退役;若存在则 policy 失败。生产 Agent selection / safety / interface 权威为 leafContractFinal与ProductDecl;agent_metadata_inject.go/InstallBuildTimeAgentMetadataJSON仅作cmd_schema_catalogCI/local dump 辅助,不得作为生产权威。
Schema 不调用 MCP tools/list,不访问网络,也不读取用户本地 discovery cache。
flag / help / schema 参数面同源(已决策):Contract / LeafSpec 为 CLI 表面权威;分层字段归属与门禁 ID 见 flag-help-schema-homology.md。
2. 单向数据流
identity collector (CollectIdentitySpecs)
walks live Cobra leaves carrying ContractFinal.Identity;
reviewed exclusions applied; single identity source
(reviewed schema_command_registry/ retired)
|
v
EffectiveCommandRegistry
|
v
exact binder to live Cobra tree
+ native identity consistency assertions
|
v
BoundCommandRegistry
|
v
live Cobra flag facts / typed parameter metadata
+ leaf Contract (Safety / ContractDecl / ParamDecl → contract_final)
+ ProductDecl (product routing prose; production Agent authority)
+ schema_parameter_mapping_ledger.go (reviewed mapping exclusions / removals)
+ leaf Contract.Interface / ParamDecl (declared interface facts)
+ skills/mono Markdown (evidence only; not concatenated)
|
v
source adapters + resolvers
|
v
one typed SchemaRegistry
(one ToolSpec per command)
+
typed SchemaIndex
+-----------+-----------+
| |
v v
build-time typed gates RegisterSchemaSourceRoot
-> ResolveSchemaBuild
(runtime assembly; lazy Once)
|
v
SchemaRegistry + SchemaIndex
+ ResolveMeta projection cache
(in-process map; not gob/json fixture)
|
+---------------------+------------------+
| | |
overview/product/group leaf --all
projections projection full projection
| | |
+---------------------+------------------+
|
v
runtime query + delivery gates
(cmd_schema_catalog = CI/local dump only;
InstallBuildTimeAgentMetadataJSON = dump helper,
not production Agent authority)
--help 是 Cobra 自身的人类可读投影,不从 Catalog 生成。Schema projections 和 --help 共享同一真实 Cobra 命令面,但承担不同职责。Binder 之后不得再从 annotation、已退役 hint overlay 或生成 JSON 重新解析 command identity。
3. 与 Lark 的关系
DWS 与 Lark 保持架构同构,而不是强行复制字段:
| Lark 分层 | DWS 对应层 |
|---|---|
| typed command/metadata registry | EffectiveCommandRegistry、BoundCommandRegistry 与最终 SchemaRegistry |
| navigation catalog/index | 从同一 ToolSpec 派生的 SchemaIndex |
| schema renderer/envelope | overview、product/group、leaf、--all projections |
| API Commands ← 平台 OAPI meta | 不作为 DWS 主路径;可选 1:1 MCP 透传子集见同源文档 §5 |
| Shortcuts ← 手写声明 + Execute | LeafSpec / Shortcut + Contract 表面(路径 A) |
共同点是:强类型 registry 持有已审核、已绑定、已解析的事实,index 只负责确定性导航,renderer 只投影,不重新读取来源或做 precedence。DWS 的 identity collector 从携带 ContractFinal.Identity 的 live Cobra leaves 收集 identity,绑定前生成唯一的 EffectiveCommandRegistry(reviewed schema_command_registry/ 已退役),因此不存在 “native-first”、“legacy registry fallback” 或 Catalog fallback。飞书也是分层单权威(API 用平台 meta,Shortcut 用手写契约),不是全家只有 meta——DWS 对齐的是这一分层,而不是「用 MCP meta 生成全部 CLI」。
DWS 内部 resolved model 为:
SchemaRegistry
-> []ProductSpec
-> []ToolSpec
-> ToolIdentitySpec
-> []ParameterSpec
-> RuntimeSchemaConstraints + []RuntimeSchemaPositional
-> SafetySpec
-> InterfaceSpec
-> SelectionSpec
-> map[field]FieldProvenance
字段合并和 precedence 在进入该模型前完成。map[string]any/flat JSON 只允许存在于 renderer 和 snapshot/wire boundary,不能作为内部 resolver、navigation 或 gate 的第二套数据模型。
DWS 当前对外仍保留兼容 wire:leaf 使用 flat parameters,安全和选择字段也保持现有键名。架构对齐不等于未版本化地切换到 Lark inputSchema/outputSchema/_meta envelope;若未来提供该格式,应作为明确版本的新投影,并保留现有兼容输出。
4. 来源职责
| 来源 | 负责内容 | 明确不负责 |
|---|---|---|
Contract / LeafSpec / corecmd.Spec |
CLI 表面权威:flags、defaults、required、enum、关系约束、运行时 Risk;编译为 cobra 与 help | canonical identity、selection 文案、虚构 RPC |
identity collector(CollectIdentitySpecs) |
从 live Cobra leaves 的 ContractFinal.Identity 声明收集稳定 canonical identity、primary CLI path、alias、exposure 和导航(reviewed schema_command_registry/ 已退役) |
创建 Cobra 命令/flag、参数、安全、endpoint/token |
reviewed exclusions(ReviewedRuntimeSchemaExclusions) |
exact、reviewed、带 reason 地将指定 public runnable leaf 排除出 effective 表面 | 运行时 fallback、prefix/wildcard 排除、创建命令 |
| Go/Cobra | Contract 编译后的可执行投影:路径是否真实可执行、Cobra 接受的 flag、DefValue、help 文本 | 稳定 canonical identity、Agent 场景选择、虚构 RPC;不得成为与 Contract 平行的第二套 flag 权威 |
| native Schema identity annotations | implementation-side consistency evidence;存在时必须与 EffectiveCommandRegistry 精确一致 |
提供、补全、推断或覆盖 identity |
| typed parameter metadata / constraints | 由 Contract 约束投影而来的 require_one_of / 互斥等;以及仍需 reviewed 的 required_when 等 |
命令 identity |
schema_parameter_mapping_ledger.go |
CLI flag 无直接 RPC property 的 exclusions / removals | 命令发现、risk 推断、创建 CLI flag;property 交付归 ParamDecl.Property |
leaf Contract.Interface / ParamDecl |
声明的 RPC identity 与 interface_* 事实(schema_mcp_metadata.json 已退役) |
CLI identity、运行时路由、创建 CLI flag、risk 推断 |
ProductDecl + leaf Contract.Selection |
reviewed selection / product routing prose(contract_final) |
创建 Cobra 命令或参数、改写 safety;schema_hints/ 已退役 |
| Skills/Markdown | 产品路由、工作流和使用建议 | 命令存在性和 flag 事实 |
cmd_schema_catalog CI/local dump(可选 schema_catalog/ / meta-index) |
resolved registry 的兼容序列化快照,仅供 jq/determinism;不得提交为 runtime 来源 | production delivery、ResolveMeta 权威、identity fallback、手工修复源 |
identity collector 从 live Cobra leaves 的 ContractFinal.Identity 声明生成 CommandSpec,应用 reviewed exclusions 后按确定性规则索引为 effective registry;从 binder 开始,下游只看到一个稳定 identity/navigation 模型。reviewed schema_command_registry/ 已退役,其历史角色(稳定 canonical identity/navigation 事实源)由 collector 承接。旧 wire 中的 surface_hash / surface_tools 字段仅为兼容名称,语义已经是 effective Registry hash/coverage,不构成第二事实源。
4.1 flag / help / schema 同源(路径 A + 嵌入)
完整决策、字段归属表、HOM-* 门禁规划与可选 MCP 透传准入条件见 flag-help-schema-homology.md。
摘要:
- 同源面:Contract → cobra flags ≡
--helpFlags ≡ 嵌入注解后的 schemaparameters/ 关系约束;显式Risk经dws.schema.riskoverlay 进 Schema Safety。 - 嵌入点:
command.embedContractIntoSchema写入dws.schema.contract/ property / type / required;AnnotateConstraints写入 constraints;Schema 组装(runtimeToolSpecFromMetadata/ResolveSchemaBuild)消费这些注解进入 typedSchemaRegistry(runtime assembly;非go:embedcatalog 交付)。 - 硬规则:CLI 表面事实 = 声明(Contract 数据字段)OR 人工标注;禁止纯推断。非 CLI 表面字段(identity / selection / interface)必须有评审源。声明写法见同源文档 §1.2;标注见 §1.3;
ToolSpec全字段权威见 RFC §5.0.4 / 同源 §1.4。 - 非同源面(有意):identity(collector)、selection 文案(ProductDecl / leaf
Contract.Selection)、RPC 形状(MCP meta 仅interface_*)、dry-run 正能力 registry。 - 禁止:以 MCP meta 为主通道生成 Leaf/Shortcut 的 flag;已退役的 hint overlay 改写 type/required/default;Schema 字段无权威归属。
5. 统一解析与 precedence
5.1 Identity
- identity collector(
CollectIdentitySpecs)是 stable canonical identity、primary path、alias 和 navigation 的唯一基础事实源:每个携带ContractFinal.Identity的 runnable Cobra leaf(含 Hidden deprecated/migration shims)贡献一条 identity,reviewed exclusions 精确应用;reviewedschema_command_registry/已退役,其历史角色由 collector 承接。 - Collector 输出的
CommandSpec在索引时 fail-closed 校验 canonical/product/path/alias/visibility 的合法性与唯一性;重复 identity、alias 复用 primary path 或 alias collision 全部失败,不能按 precedence 静默覆盖。 - Binder 必须把 effective entry 的 primary path 和每个 alias 精确解析到同一个真实 executable leaf;stale path、phantom path、重复 identity 或 alias collision 全部失败。
- Native identity annotation 是可选的一致性证据:存在时必须与 effective entry 精确一致;缺失不触发补写、推断或 fallback。
- Public runnable Cobra leaf 未进入 effective registry 时,必须存在 exact、reviewed、带 reason 的 exclusion;不得用 prefix/wildcard 排除。
- Identity 不做名称推断,不从 Catalog/generated metadata fallback,也没有多来源 winner。
删除 native materialization 前已做写入审计:旧
ApplyNativeRuntimeSchemaContracts 的唯一写操作是对已存在命令调用
AttachRuntimeSchema,只写 command identity 的 product/tool/source annotation;
它不写 flag property/type/required、constraints、positionals、title/description
或 interface mapping。这些字段原本已分别由 parameter binding/metadata、
constraint、Cobra help 和 interface resolver 提供,因此删除该过渡层没有数据迁移缺口。
CI 同时禁止重新加入 generated native contracts 或 materialization 入口。
Identity 输入审计(registry 已退役)
历史上 identity 来自 reviewed schema_command_registry/(registry.json +
products/*.json,由随附 JSON Schema 校验)。该 reviewed registry 已退役,
改由 identity collector 承接:identity 现在由 CollectIdentitySpecs 从 live
Cobra 树的 ContractFinal.Identity 声明收集,输入契约即声明本身。严格 Go
索引(indexCommandSpecs)继续 fail-closed 校验:
- canonical identity、
source_product_id和精确 CLI path 的格式; aliases唯一且不能复用 primary path;visibility只允许public | compat | internal,省略时明确归一化为public;- primary path、alias、canonical 和 product 之间的交叉唯一性约束。
Registry semantic hash 仍覆盖 canonical、primary CLI path、alias 集合、
source_product_id 和 normalized visibility。格式、顺序以及省略的等价默认值
不改变 hash;上述任一稳定契约字段变化都必须改变 hash。测试逐字段验证这一点,
不使用当前命令数量作为常量。
普通 go generate ./internal/cli 只生成
param_aliases_generated.go;production Catalog / ResolveMeta 由 runtime
ResolveSchemaBuild 装配(deliverySchemaCatalog Once 后缓存 Meta 投影)。
cmd_schema_catalog 仅按需打 CI/local dump;其 InstallBuildTimeAgentMetadataJSON
inject 仅服务 dump,生产 Agent 权威仍是 leaf ContractFinal / ProductDecl。
不写也不 embed schema_agent_metadata/。drift policy 禁止已退役的
schema_command_registry/ 在生成前后重新出现;原独立脚本
check-schema-command-registry.sh 的 registry-agnostic side guards(禁用旧
native materialization 符号、go:generate 单轨、lazy loader 纪律)已迁入
check-schema-catalog.sh。
5.2 Parameter
每个字段按明确的来源 precedence 选择一次,并把 winner、候选值和来源写入 provenance。precedence 与值无关:不能因为 required=true 看起来更严格就让它越级获胜。更高优先级的 reviewed manual override 可以把 required、映射、interface type 或描述调高,也可以调低。
实现中的参数字段顺序固定为:
versioned binding > command constraint > typed metadata
> native/Cobra contract (ParamDecl / ContractFinal)
> MCP metadata > inference/default
命令 title / description 使用独立但同样确定的文本顺序:
description: Cobra Long > ContractDecl description (contract_final) > MCP metadata > inference
(Long 胜出时 provenance = cobra_help / cobra_help_preferred)
title: ContractDecl / ContractFinal > Cobra Short > MCP metadata > inference
因此多个 CLI leaf 复用同一个 RPC 时,通用 RPC 文案只能作为未选中的
provenance candidate 保留;参数级 RPC 文案可进入 interface_description,
但不得覆盖 leaf 自己的标题和执行语义。
Cobra hard-required 是独立的 executable fact,并通过 cli_required/provenance 保留;它不应在 renderer 中再次静默改写已经解析的 Agent projection。
5.3 Safety、selection 与 interface
effect、risk、confirmation、idempotency、selection 和 interface disposition 同样按 source precedence 解析,而不是按值的“严格程度”合并。更高优先级的 reviewed explicit/manual source 可以升高或降低最终值;同 precedence 的不同值必须报冲突。
最终 interface disposition 还必须满足 conflict matrix:
mode与availability正交:mode只允许mcp | local | composite,availability只允许available | unavailable;unavailable不是第四种 mode。mcp + available:只表示命令可由一个 pinned、参数可映射且语义等价的interface_ref完整表达;本地 wrapper 只是固定默认值或投影返回值时,也必须先证明参数和执行语义没有漂移。local + available:仅用于纯本地进程、静态数据或策略操作,不得携带 directinterface_ref;“远端 RPC 尚未进入 pinned metadata”不能归类为 local。composite + available:用于多 RPC、条件路由、本地投影,或 reviewed unpinned remote adapter;不得用单个interface_ref冒充完整实现,且必须提供 reviewed reason。未来需要表达多个 RPC 时使用单独的复合接口模型。- 任意合法 mode +
unavailable:不得携带interface_ref,必须提供明确 reason,并且 Agent 不得把它当作可用接口。
6. Schema、Help 与业务数据边界
| 问题 | 事实源 |
|---|---|
| 当前二进制是否暴露命令、Cobra 接受哪些 flags | dws <path> --help |
| Agent 选哪个命令、CLI 参数/required/约束、risk/confirmation | Agent leaf dws schema "<path>" --compact |
| CLI↔RPC 参数映射、接口绑定、provenance | full leaf 配合 --jq / --fields 精确投影 |
| 钉钉中的文档、文件、日程、消息等实际数据 | 真正执行 dws doc read、dws drive search 等 read/search/list 命令 |
Schema 和 Help 冲突是契约漂移,不能静默猜测:
- 执行参数以 Cobra 实际接受的 flags 为准;不要发送 Help 中不存在的 flag。
- 安全语义冲突时不要采用更宽松值。先按更保守的解释确认;如果无法确定安全执行方式,停止并报告漂移。
- Schema/Help 只完成命令发现和契约读取。需要业务结果时,必须继续执行真实 read/search/list 命令。
上述运行时漂移策略不改变构建期的 value-neutral precedence;前者是在契约已经互相矛盾时保护用户,后者是在确定性生成同一契约。
7. 查询投影
dws schema # 产品紧凑概览
dws schema calendar --compact # Agent 产品摘要
dws schema "calendar event" --compact # Agent 分组摘要
dws schema "calendar event create" --compact # Agent leaf
dws schema "calendar event create" # full leaf,仅用于映射/provenance 审计
dws schema --all # 所有工具的完整 leaf 导出
schema list 是根概览的兼容入口。
schema --all 必须包含最终 SchemaIndex 中每个 tool 的完整 leaf 参数、约束和安全语义;无业务参数的命令也要包含空 parameters 对象。它用于审计、CI 和参数防丢 baseline,但输出很大,普通 Agent 命令发现不得使用,应按 overview -> product/group -> leaf 渐进查询。
--compact 是普通 Agent 查询的规范视图:通过正向字段白名单保留选参、约束与安全语义,full 新增字段不会自动进入 Agent 上下文。省略它的 leaf 包含参数 property、接口绑定和 provenance,只用于定向审计;schema --all --compact 也可执行,但不能作为完整兼容性 baseline。
兼容旧二进制时,如果 Schema 查询返回 unknown_flag: --compact,只去掉 --compact 重试同一个查询。这是展示能力降级,不代表 leaf 缺失,也不能改用 Schema 查询业务数据。
8. 生成与发布
当 Cobra、flag、identity、binding、leaf Contract / ProductDecl 或 Skill 发生变化时:
-
审核真实 Cobra 变化,确认命令和 flag 已实际存在。新增或修改稳定 command identity、primary CLI path 或 alias 现在通过 leaf Contract 的
ContractFinal.Identity声明完成(identity collector 据此收集;reviewedschema_command_registry/已退役)。参数、Skill 或 metadata 单独变化时不要机械改写 identity 声明,也不要从旧 Catalog 反向生成它。 -
不应进入稳定 Agent 契约的 public runnable leaf 使用 reviewed exclusions(exact path、带 reason)。Native identity annotation 若存在,应作为与 identity 声明一致的实现断言维护,而不是用来 materialize identity。
-
生成参数别名并验证运行时 Schema 组装。
go generate ./internal/cli只运行cmd_param_aliases;cmd_schema_catalog仅按需生成 CI/local dump。生产权威为 leafContractFinal/ProductDecl;CI dump 可经agent_metadata_inject.go/InstallBuildTimeAgentMetadataJSON在内存中注入 Agent metadata,不写schema_agent_metadata/:make generate-schema go generate ./internal/cli # 可选:生成 artifacts/ 下的 CI/local dump make generate-schema-catalog
cmd_schema_agent_metadata 可保留为非交付工具/测试,但不是 go:generate 入口,也不应再作为发布步骤。
生成文件只有 internal/cli/param_aliases_generated.go(参数别名生成物)。cmd_schema_catalog 的 Catalog 和 meta-index 是可选 CI/local dump,不是交付物,且不得写入或提交到 internal/cli/。
schema_agent_metadata/、schema_agent_metadata_audit.json 与 schema_hints/ 已退役;若存在则 policy 失败。只编辑来源;不要手工编辑或提交 Catalog / meta-index dump。
9. Completeness 与 final-delivery invariant
门禁必须验证最终交付对象,而不是某个中间层或数量:
- 每个 public runnable Cobra leaf 要么能通过最终 embedded
SchemaIndex查询,要么有 exact、reviewed、带 reason 的 exclusion。 - 每个最终 canonical path、primary CLI path 和 alias 都必须解析到同一个可执行 leaf;不得有 phantom path 或 collision。
EffectiveCommandRegistry、SchemaRegistry/SchemaIndex与 Catalog canonical sets 必须精确一致(含组装时内存 inject 的 Agent metadata 语义),不能只比较 count。- Leaf payload、
--all中对应 tool 和 Catalog full tool 必须是同一个 resolvedToolSpec的内容级等价投影,并通过 production loader round-trip。 - overview/product/group summary 与 Catalog summary 必须等于同一个
ToolSpec.ToSummaryPayload();alias 查询只允许cli_path和is_alias这两个视图字段变化。 - 每个最终字段及 parameter field 的 provenance winner value 必须与 delivered value 精确一致;不能只验证 provenance source、count 或字段是否存在。
- 每个 MCP
interface_ref必须在 pinned interface registry 精确存在;local/composite/unavailable 必须满足同一 conflict matrix。 --all的 tool set 必须与最终 index 一对一,且每个工具包含完整参数契约。- 连续两次生成必须字节稳定,提交的生成物不得漂移。
- 同源门禁(规划,见同源文档 §4):受管命令逐步满足
HOM-P1–P3(parameters ≡ cobra/Contract)、HOM-S1–S3(Safety/Risk 对齐)、HOM-I1(interface 不创建 flag)、HOM-D1(help ≡ schema parameters)。hints 不得作为 type/required/default 的 winner。
推荐本地验证:
make generate-schema
./scripts/policy/check-generated-drift.sh
./scripts/policy/check-schema-catalog.sh
go test ./internal/cli ./internal/app ./internal/generator/... -count=1
10. 明确禁止
- 运行时调用 MCP
tools/list或访问网络生成 Schema。 - 从
schema_catalog/等生成 JSON 反向创建/补齐 Cobra leaf、flag、CommandRegistry 或下一轮 Catalog。 - 重新引入
schema_agent_metadata/(或 audit JSON)作为交付物、go:embed目标,或把它写回go:generate入口。 - 从 MCP meta / 已退役的
schema_mcp_metadata生成或补齐 LeafSpec/Shortcut 主路径的 CLI flag(interface overlay 除外);未满足同源文档 §5 准入条件时启用「MCP 透传生成通道」。 - 把 native annotation、legacy registry 或 Catalog 当作 identity fallback;或在
EffectiveCommandRegistry之后再次选择 identity winner。 - renderer、query 或 gate 在
SchemaRegistry之后重新读取 source 并做第二次 merge。 - 用 prefix/wildcard exclusion 隐藏未来命令。
- 让 ProductDecl / leaf
Contract、CommandRegistry 或 interface metadata 宣称一个不存在的命令、flag 或 RPC 可用。 - 重新引入
schema_hints/(含 selection/metadata/imported/audit JSON)或任何 HintFile overlay,并在与 Contract/cobra 冲突时赢得 type/required/default。 - 把
schema --all当作普通业务数据查询,或把其完整结果无条件注入 Agent 上下文。 - 将 LeafSpec、
+shortcut或 write-guard/cursor/多步命令注册为mcp_passthrough表面。