|
|
@@ -0,0 +1,346 @@
|
|
|
+# Application API 0.1 草案
|
|
|
+
|
|
|
+> **受众**:业务应用团队
|
|
|
+>
|
|
|
+> **状态**:`[TARGET / DRAFT]`,尚未实现,不可 import,暂无兼容承诺
|
|
|
+>
|
|
|
+> **目标里程碑**:M3A 提供最小装配能力,M3B 补齐候选和事件投影;真实 reference example 通过后再讨论冻结 API
|
|
|
+
|
|
|
+## 1. 先说明:现在能做什么,本文又是什么
|
|
|
+
|
|
|
+当前框架已经能直接运行 Agent,并提供 Recursive 任务树、TaskProtocol、Context 授权、工具门禁、Artifact 解析、Validator、预算以及停止和恢复。业务也可以通过构造 `AgentRunner` 注入工具注册表、验证策略和 `ArtifactResolver`。
|
|
|
+
|
|
|
+当前尚没有“应用”这一层稳定接口:没有应用 ID/版本、应用级角色隔离、Provider 注册、候选生命周期,也不能只凭一个 Trace 精确找回当初的业务装配。因此本文不是使用手册,而是业务团队和框架团队共同评审的接口合同草案。
|
|
|
+
|
|
|
+本文所有类型都分为三类:
|
|
|
+
|
|
|
+- `[CURRENT]`:代码中已经存在,可按现有文档使用。
|
|
|
+- `[M2 TARGET]`:M2 计划实现的 TaskProgress 能力。
|
|
|
+- `[M3 TARGET]`:M3 计划实现的应用装配、候选或投影能力。
|
|
|
+
|
|
|
+本文中的结构示例是**设计记法**,不是 Python 代码。现在创建同名文件或执行 `from cyber_agent import AgentApplication` 都不会工作。
|
|
|
+
|
|
|
+框架团队的代码证据、状态权威和责任边界见 [M1 应用框架设计基线](./application-framework-m1.md)。
|
|
|
+
|
|
|
+## 2. 业务接入的心智模型
|
|
|
+
|
|
|
+一套应用由一个不可变描述和若干可替换 Provider 组成:
|
|
|
+
|
|
|
+```text
|
|
|
+AgentApplication(声明“这是什么应用”)
|
|
|
+ ├─ ApplicationRef(身份和版本)
|
|
|
+ ├─ AgentRole[](角色、Prompt、Skill、模型和子角色边界)
|
|
|
+ ├─ ToolSet[](允许使用哪些业务工具)
|
|
|
+ ├─ TaskContextProvider(有哪些业务资料可供授权)
|
|
|
+ ├─ ArtifactResolver [CURRENT](如何可信地读取产物)
|
|
|
+ ├─ CandidateRepository(候选内容如何存储、分叉和合并)
|
|
|
+ ├─ QualityCheckProvider(有哪些确定性业务规则)
|
|
|
+ ├─ RunEventProjector(如何投影业务数据库和 UI)
|
|
|
+ └─ RunLimits(应用允许的资源上限)
|
|
|
+```
|
|
|
+
|
|
|
+应用只描述业务能力。框架负责校验描述、把它编译成现有 Runner/ToolRegistry/Validator 能理解的配置、固化本次运行的解析结果,并在恢复时验证完全一致。
|
|
|
+
|
|
|
+应用不创建第二个 Runner,不接管 TaskProtocol,不直接修改 Trace,也不通过回调绕过工具确认或 Validator。
|
|
|
+
|
|
|
+## 3. 公共草案对象
|
|
|
+
|
|
|
+### 3.1 `ApplicationRef` `[M3 TARGET]`
|
|
|
+
|
|
|
+应用版本的不可变引用,也是启动、恢复和审计时的身份。
|
|
|
+
|
|
|
+| 字段 | 含义 | 约束 |
|
|
|
+|---|---|---|
|
|
|
+| `application_id` | 稳定应用 ID,例如 `creative.reference` | 由组织命名,不能依赖本地目录名 |
|
|
|
+| `application_version` | 可部署、可解析的应用版本 | 同一版本的行为声明不可被原地改写 |
|
|
|
+| `config_hash` | 解析后行为配置的 SHA-256 | 新 Run 由框架计算;续跑必须精确匹配 |
|
|
|
+
|
|
|
+公共名称不带 `V1`。当它随 Trace 落盘时,序列化对象必须额外包含 `schema_version`。
|
|
|
+
|
|
|
+### 3.2 `AgentApplication` `[M3 TARGET]`
|
|
|
+
|
|
|
+不可变应用描述对象,回答“这个应用允许框架装配什么”。它不是 Runner,也不保存连接池、Token 或运行时客户端。
|
|
|
+
|
|
|
+草案字段:
|
|
|
+
|
|
|
+| 字段 | 含义 |
|
|
|
+|---|---|
|
|
|
+| `application_id` / `application_version` | 应用稳定身份 |
|
|
|
+| `root_role` | 新 Run 的根角色 ID |
|
|
|
+| `roles` | 应用命名空间内的 `AgentRole` 目录 |
|
|
|
+| `tool_sets` | 可被角色引用的 `ToolSet` 目录 |
|
|
|
+| `context_provider` | 业务资料枚举端口及其版本描述 |
|
|
|
+| `artifact_resolver` | 现有只读 Artifact 解析端口 |
|
|
|
+| `candidate_repository` | 候选内容和合并端口 |
|
|
|
+| `quality_provider` | 确定性业务规则端口及其版本描述 |
|
|
|
+| `event_projector` | 可选业务投影端口 |
|
|
|
+| `run_limits` | 应用整体资源上限 |
|
|
|
+
|
|
|
+应用描述在注册后不可变。要修改 Prompt、工具能力、规则或资源边界,应发布新的 `application_version`,不能替换相同版本的内容。
|
|
|
+
|
|
|
+### 3.3 `AgentRole` `[M3 TARGET]`
|
|
|
+
|
|
|
+角色属于应用命名空间,不再写入进程全局的同名 Preset。
|
|
|
+
|
|
|
+| 字段 | 含义 |
|
|
|
+|---|---|
|
|
|
+| `role_id` | 应用内唯一角色 ID |
|
|
|
+| `description` | 给装配器和根角色理解的职责说明 |
|
|
|
+| `model` / `model_parameters` | 模型及影响行为的生成参数 |
|
|
|
+| `prompt` / `prompt_hash` | 版本化 Prompt 引用及解析后 hash |
|
|
|
+| `skills` | Skill ID、版本和顺序 |
|
|
|
+| `tool_sets` | 角色可见的 ToolSet ID;子 Task 仍受父级能力交集限制 |
|
|
|
+| `allowed_child_roles` | 此角色允许创建的子角色集合 |
|
|
|
+| `default_validation_scopes` | 默认要求 Validator 检查的范围 |
|
|
|
+| `run_limits` | 角色级限制,与应用和框架上限取最严格值 |
|
|
|
+
|
|
|
+角色不能通过 Prompt 放宽工具、Context、预算、Artifact 或子角色门禁。Prompt hash 必须基于框架真正发送给模型的解析后内容,而不是只 hash 文件路径。
|
|
|
+
|
|
|
+### 3.4 `ToolSet` `[M3 TARGET]`
|
|
|
+
|
|
|
+应用级工具声明。它最终编译进现有 `ToolRegistry`,不会形成第二套注册表或执行器。
|
|
|
+
|
|
|
+每项工具声明至少需要:
|
|
|
+
|
|
|
+- 稳定工具名和输入 schema。
|
|
|
+- 实现绑定的版本标识。
|
|
|
+- 是否需要人工确认、哪些参数允许确认时编辑。
|
|
|
+- URL policy;声明 URL pattern 时,调用上下文必须有匹配的 `page_url`。
|
|
|
+- 副作用分类和幂等说明,供审计与崩溃恢复判断。
|
|
|
+- 工具分组和可被哪些角色引用。
|
|
|
+
|
|
|
+最终可执行集合仍由框架计算:应用声明、角色声明、父级转授、Run 级精确白名单和框架硬禁用项取交集。业务工具实现不得直接调用注册表的内部 dispatch 绕过这一步。
|
|
|
+
|
|
|
+### 3.5 `TaskContextProvider` `[M3 TARGET]`
|
|
|
+
|
|
|
+业务实现的资料枚举端口。Provider 回答“当前 Task 有哪些候选资料”,框架决定“哪些资料被授权、继承和放入模型上下文”。
|
|
|
+
|
|
|
+Provider 的输入至少包含只读的应用引用、root/trace/task identity、当前 TaskBrief revision、父级已授权 ContextRef 和预算视图。输出的是资料描述,不是直接拼接后的 Prompt:
|
|
|
+
|
|
|
+| 元数据 | 用途 |
|
|
|
+|---|---|
|
|
|
+| `source_id` / `source_version` | 稳定来源和版本 |
|
|
|
+| `content_hash` | 内容寻址、去重和恢复校验 |
|
|
|
+| `kind` / `mime_type` | 裁剪和渲染策略 |
|
|
|
+| `inheritance` | 建议仅本 Task、允许逐边转授或禁止继承 |
|
|
|
+| `priority` / `estimated_tokens` | 预算裁剪输入 |
|
|
|
+| `authorization_metadata` | 供框架策略判断的业务归属,不等于已授权 |
|
|
|
+
|
|
|
+框架把获准资料固化为现有 ContextSnapshot/ContextRef。Provider 不直接写 `TaskBrief.context_refs`,也不能返回另一个 root 或未获授权 Task 的引用。
|
|
|
+
|
|
|
+### 3.6 `ArtifactResolver` `[CURRENT]`
|
|
|
+
|
|
|
+继续使用现有名称和协议,不新增 `ArtifactReader`。业务实现可信、只读解析;框架负责校验引用、归属和 hash,并把合法材料交给 Validator。
|
|
|
+
|
|
|
+当前权威签名位于 [`cyber_agent/core/artifacts.py`](../core/artifacts.py):
|
|
|
+
|
|
|
+```text
|
|
|
+async resolve(
|
|
|
+ ref: ArtifactRef,
|
|
|
+ root_trace_id: str,
|
|
|
+ uid: str | None,
|
|
|
+) -> ValidationMaterial
|
|
|
+```
|
|
|
+
|
|
|
+业务 Resolver 必须:
|
|
|
+
|
|
|
+- 以 `artifact_id + version` 读取不可变版本,不把“最新内容”冒充指定版本。
|
|
|
+- 校验 root 和 uid 的访问权;越权使用确定性拒绝语义。
|
|
|
+- 返回内容的 hash 与 ArtifactRef 完全一致。
|
|
|
+- 区分不存在、暂时不可用和越权,不把所有错误吞成空内容。
|
|
|
+
|
|
|
+上传、ACL 管理、索引和删除仍是业务存储职责,不进入 Resolver。
|
|
|
+
|
|
|
+### 3.7 `CandidateRef` `[M3 TARGET]`
|
|
|
+
|
|
|
+框架持有的不可变候选引用。候选内容仍在业务存储中。
|
|
|
+
|
|
|
+草案最小信息包括:candidate identity、所属 application/root/trace/task、来源 ArtifactRef、parent candidate、revision、创建原因和生命周期阶段。每次内容变化产生新 revision 或新候选,不覆盖已被 Validator 或 TaskReview 引用的历史版本。
|
|
|
+
|
|
|
+候选阶段只描述业务工作流中的 `draft / proposed / adopted / discarded` 等生命周期,不替代 Trace.status、ValidationResult 或 TaskReview。
|
|
|
+
|
|
|
+### 3.8 `CandidateRepository` `[M3 TARGET]`
|
|
|
+
|
|
|
+业务实现的候选内容端口,替代含义模糊的 `CandidateStore`。框架通过它执行以下受控能力:
|
|
|
+
|
|
|
+- 创建不可变候选版本并返回内容 hash/ArtifactRef。
|
|
|
+- 读取某个 CandidateRef 指定的精确版本。
|
|
|
+- 从一个候选 fork 新候选并保留血缘。
|
|
|
+- merge 候选,返回冲突而不是静默覆盖。
|
|
|
+- 将已被父级采用的版本写回业务目标;写回必须幂等。
|
|
|
+
|
|
|
+Repository 必须校验框架传入的 application/root/task 归属,不能仅凭 candidate_id 读写。框架负责 CandidateRef 和生命周期动作的合法性,Repository 负责内容、存储事务、冲突和业务写回。
|
|
|
+
|
|
|
+### 3.9 `QualityCheckProvider` `[M3 TARGET]`
|
|
|
+
|
|
|
+业务实现的确定性质量规则端口。它声明规则和可执行检查,框架把规则编译进现有 ValidationPlan 并统一调度。
|
|
|
+
|
|
|
+每条规则至少声明:稳定 `check_id`、规则版本、适用 scope、所需材料类型、确定性执行器、失败说明模板和建议的 `retry_from`。例如“候选正文仍含 `{placeholder}`”可以是确定性规则,但“表达是否有感染力”仍应由 LLM Validator 评价。
|
|
|
+
|
|
|
+约束:
|
|
|
+
|
|
|
+- Provider 不直接写 ValidationResult;框架统一生成完整结果。
|
|
|
+- Provider 不直接修改 TaskProgress 或 Candidate 生命周期。
|
|
|
+- 回退建议只是 Validator 结果的一部分,父级仍通过 TaskReview 决定修订、重拆或上行。
|
|
|
+- 新 Run 固化规则 ID、版本和配置 hash;续跑不能加载当前默认的新规则替换旧规则。
|
|
|
+
|
|
|
+### 3.10 `RunEventProjector` `[M3 TARGET]`
|
|
|
+
|
|
|
+业务实现的异步投影端口。它从现有 Trace 事件流按 cursor 消费,把权威状态投影到业务数据库、UI、通知或分析系统。
|
|
|
+
|
|
|
+投影器必须满足:
|
|
|
+
|
|
|
+- 以 application/root/trace 和 event_id 作为幂等键。
|
|
|
+- 只提交连续 cursor;同一事件重复投递不能产生重复业务写入。
|
|
|
+- 能在进程重启后从最后 cursor 重放。
|
|
|
+- 对未知的新事件类型安全忽略或存入待升级队列。
|
|
|
+- 投影失败只影响业务视图新鲜度,不回滚 Agent Trace,不阻塞已经完成的协议动作。
|
|
|
+
|
|
|
+它不是同步 EventBus。业务不能把“投影成功”当作 Trace 状态转换的前置条件;确实需要参与事务的业务动作应建模为受门禁工具或 Repository 写回。
|
|
|
+
|
|
|
+### 3.11 `RunLimits` `[M3 TARGET]`
|
|
|
+
|
|
|
+应用可声明:模型轮次、递归深度、孩子数、并发孩子数、Token、成本、墙钟时间和单类资料大小上限。
|
|
|
+
|
|
|
+有效限制为以下各层中最严格的一项:
|
|
|
+
|
|
|
+```text
|
|
|
+框架硬上限 ∩ 部署策略 ∩ AgentApplication ∩ AgentRole ∩ 本次 Run 请求可收紧值
|
|
|
+```
|
|
|
+
|
|
|
+本次 Run 只能收紧,不能放宽已经注册的限制。解析后的限制进入恢复快照;停止、重启和回溯不能重置已消耗资源。
|
|
|
+
|
|
|
+## 4. M2 的 `TaskProgress` 如何被业务使用
|
|
|
+
|
|
|
+`TaskProgress` 是 `[M2 TARGET]`,不是应用 Provider。业务 UI 可读,Agent 通过框架命令更新,业务代码不能直接写协议 context。
|
|
|
+
|
|
|
+它只记录当前 Task 的推进事实,例如:
|
|
|
+
|
|
|
+- `phase`:理解问题、收集证据、形成方案、生成候选、准备提交等推进阶段。
|
|
|
+- `questions` / `blockers`:待确认问题和阻塞因素。
|
|
|
+- `findings` / `hypotheses`:带 ContextRef/ArtifactRef 的结构化发现与假设。
|
|
|
+- `work_items`:已经尝试、待尝试或放弃的工作项。
|
|
|
+- `candidate_refs`:本 Task 当前产生或引用的候选。
|
|
|
+- `decision_rationale`:简短、可审计的选择理由。
|
|
|
+
|
|
|
+它不拥有 `completed/passed/failed` 终态,不复制 TaskBrief.target、ValidationResult 或 TaskReview.next_action,也不保存模型原始思维链。
|
|
|
+
|
|
|
+## 5. 新 Run 与恢复合同
|
|
|
+
|
|
|
+### 5.1 新 Run
|
|
|
+
|
|
|
+框架按以下顺序创建应用 Run:
|
|
|
+
|
|
|
+1. 按 `application_id + application_version` 解析不可变 AgentApplication。
|
|
|
+2. 校验根角色、子角色图、工具、Provider 版本和 RunLimits。
|
|
|
+3. 解析 Prompt/Skill、工具 schema、质量规则和行为配置。
|
|
|
+4. 对规范化后的行为声明计算 `config_hash`。
|
|
|
+5. 将完整 ApplicationRef、根角色/角色目录 hash 和解析后的行为配置加入 RunConfigSnapshot。
|
|
|
+6. 创建 Trace 后才允许 Runner 进入模型循环。
|
|
|
+
|
|
|
+### 5.2 续跑、人工确认、回溯和 compact
|
|
|
+
|
|
|
+所有恢复入口都必须:
|
|
|
+
|
|
|
+1. 先读取 Trace 中固化的 ApplicationRef 和 RunConfigSnapshot。
|
|
|
+2. 从内部 Registry 解析完全相同的 `application_version`。
|
|
|
+3. 重新计算并比对 config hash、角色 hash、工具和规则版本。
|
|
|
+4. 一致后恢复 Provider 运行时对象,再进入现有恢复流程。
|
|
|
+
|
|
|
+以下情况失败关闭:应用不存在、版本不存在、hash 不匹配、角色或规则缺失、Provider 无法恢复。框架不得用当前默认应用、最新 Prompt 或新规则继续执行。
|
|
|
+
|
|
|
+业务请求在续跑时不能覆盖已固化角色、工具、模型、质量规则或 RunLimits。一次性的框架动作(例如现有 reflect/compact 的 side branch)仍由框架恢复协议控制。
|
|
|
+
|
|
|
+### 5.3 config hash 包含与排除
|
|
|
+
|
|
|
+必须进入 hash 的行为配置:
|
|
|
+
|
|
|
+- 应用 ID/版本和规范化声明 schema 版本。
|
|
|
+- 解析后的角色图、Prompt hash、Skill 版本和模型参数。
|
|
|
+- 工具名、schema、实现版本、确认/可编辑参数和 URL policy。
|
|
|
+- Provider 的稳定 ID、协议版本和影响行为的公开配置。
|
|
|
+- 确定性规则 ID、版本、输入声明和配置。
|
|
|
+- RunLimits、默认 validation scopes 和资料继承策略。
|
|
|
+
|
|
|
+不得进入 hash 的运行时秘密:
|
|
|
+
|
|
|
+- API key、密码、访问令牌和临时签名 URL。
|
|
|
+- 数据库连接池、HTTP client、线程锁和进程对象。
|
|
|
+- Provider 当前健康状态、缓存内容和监控指标。
|
|
|
+
|
|
|
+秘密虽不进入 hash,但恢复时凭证缺失仍应启动失败,不能降级成另一数据源。
|
|
|
+
|
|
|
+## 6. 内部装配概念,不是首版公共 API
|
|
|
+
|
|
|
+下列名称用于框架实现和设计沟通,业务代码不应 import:
|
|
|
+
|
|
|
+| 名称 | 内部职责 |
|
|
|
+|---|---|
|
|
|
+| `ApplicationRegistry` | 按 ID/版本定位不可变应用声明 |
|
|
|
+| `ApplicationBinding` | 保存一次解析后的应用依赖、hash 和恢复材料 |
|
|
|
+| `ApplicationRuntime` | 把 Binding 编译成现有 AgentRunner 的 RunConfig、ToolRegistry、ValidationPolicy 和 Resolver |
|
|
|
+
|
|
|
+业务入口只需要提交应用引用和业务输入。内部结构未来可以重构,不作为 0.1 公共兼容面。
|
|
|
+
|
|
|
+## 7. 失败语义
|
|
|
+
|
|
|
+| 场景 | 预期行为 |
|
|
|
+|---|---|
|
|
|
+| 应用或版本不存在 | 新 Run 拒绝创建;恢复 Run 失败关闭 |
|
|
|
+| config hash 或角色 hash 不匹配 | 拒绝恢复,报告不匹配对象,不自动迁移 |
|
|
|
+| Context Provider 暂不可用 | 资料标记 unknown 或 Run 暂停/失败,不能返回伪空资料 |
|
|
|
+| Artifact 不存在、暂不可用、越权 | 继续使用现有 failed/unknown/error 确定性映射 |
|
|
|
+| Candidate 归属不匹配 | 拒绝访问并记录审计事件 |
|
|
|
+| merge 冲突 | 返回结构化冲突,由 Agent/父级决定下一步,不静默覆盖 |
|
|
|
+| 确定性质量检查异常 | ValidationResult 保持计划完整并失败关闭 |
|
|
|
+| Event Projector 失败 | 保留 cursor,稍后重放;不修改权威 Trace |
|
|
|
+| Provider 凭证缺失 | 应用装配失败,不切换到匿名或默认 Provider |
|
|
|
+
|
|
|
+## 8. 业务团队的最小实现面
|
|
|
+
|
|
|
+M3 能力完成后,一套新业务应用预计只需提供:
|
|
|
+
|
|
|
+1. 一个版本化 AgentApplication 描述。
|
|
|
+2. 根角色和必要的子角色 Prompt/Skill。
|
|
|
+3. 业务工具及其 ToolSet 声明。
|
|
|
+4. 一个 TaskContextProvider,将业务资料描述给框架。
|
|
|
+5. 一个 ArtifactResolver,让 Validator 可信读取产物。
|
|
|
+6. 需要多候选时实现 CandidateRepository。
|
|
|
+7. 可确定执行的业务质量规则及 QualityCheckProvider。
|
|
|
+8. 可选 RunEventProjector,将 Trace 投影到业务数据库和 UI。
|
|
|
+9. 业务入口、最终写回和面向用户的输出解释。
|
|
|
+
|
|
|
+业务团队不应:
|
|
|
+
|
|
|
+- 修改 `AgentRunner`、TaskProtocol、TraceStore、Validator 或 ResourceBudgetController。
|
|
|
+- 直接读写 `Trace.context.task_protocol` 或伪造 ValidationResult。
|
|
|
+- 用全局 `AGENT_PRESETS` 动态注册多个应用的同名角色。
|
|
|
+- 把真实业务数据塞进框架 Trace 来替代业务 Repository。
|
|
|
+- 绕过 ToolRegistry 直接执行有副作用的工具。
|
|
|
+- 将 Projector 当作同步事务钩子。
|
|
|
+
|
|
|
+## 9. 从当前代码迁移到草案接口
|
|
|
+
|
|
|
+| 当前做法 | 目标做法 | 里程碑 |
|
|
|
+|---|---|---|
|
|
|
+| 调用方直接构造 Runner 并注入依赖 | 用 ApplicationRef 解析应用并由内部 Runtime 构造现有 Runner | M3A |
|
|
|
+| `AGENT_PRESETS` 全局注册角色 | AgentApplication 内的命名空间角色目录 | M3A |
|
|
|
+| 手工把业务资料塞入 TaskBrief | TaskContextProvider 枚举,框架生成 ContextRef | M3A |
|
|
|
+| 直接注册一组工具 | ToolSet 声明后编译进 ToolRegistry | M3A |
|
|
|
+| RunConfigSnapshot 只保存 `project_name` | 同一快照固化 ApplicationRef、角色和解析配置 | M3A |
|
|
|
+| ArtifactRef 只表示验证材料 | 原协议不变;ApplicationBinding 负责找到对应 Resolver | M3A |
|
|
|
+| 没有候选权威模型 | CandidateRef + CandidateRepository | M3B |
|
|
|
+| Validator 主要执行 LLM checks | QualityCheckProvider 增加版本化确定性规则 | M3A/M3B |
|
|
|
+| 业务订阅开放字典事件 | 稳定事件 envelope + cursor Projector | M3B |
|
|
|
+
|
|
|
+## 10. 接口进入实现前的评审清单
|
|
|
+
|
|
|
+- 同一进程注册应用 A/B 时,角色、工具、Resolver、规则和候选是否完全隔离?
|
|
|
+- 停止并重启进程后,能否只凭 Trace 解析到同一应用版本和行为配置?
|
|
|
+- Provider 是否只描述业务资料/规则,所有授权、计划和结果是否仍由框架控制?
|
|
|
+- CandidateRef 是否能证明 root/task 归属和血缘,Repository 是否校验这些边界?
|
|
|
+- 确定性规则失败时,是否能只回退产物层而保留已验证证据?
|
|
|
+- Projector 重放相同事件时,业务数据库是否保持一次效果?
|
|
|
+- 业务应用是否无需修改 Runner、TaskProtocol、TraceStore 和 Validator?
|
|
|
+
|
|
|
+用于证明这些问题的后续场景见 [reference example 验收合同](./application-reference-contract.md)。在该合同变成可运行测试前,本草案不构成兼容承诺。
|