Просмотр исходного кода

docs(m1): 建立应用框架能力、边界与状态权威基线

基于当前 Runner、Recursive 协议、Context、Artifact、Validator、预算与恢复实现,建立带代码和测试证据的能力矩阵。

明确 Trace、Goal、TaskProgress、ValidationResult、TaskReview 与 RunConfigSnapshot 的唯一状态职责,冻结框架和业务应用边界。

追加 Decision 26,约束后续应用装配、精确恢复、事件投影和公共接口命名,不引入新的运行时行为。
SamLee 1 день назад
Родитель
Сommit
105d531a53
2 измененных файлов с 281 добавлено и 0 удалено
  1. 192 0
      cyber_agent/docs/application-framework-m1.md
  2. 89 0
      cyber_agent/docs/decisions.md

+ 192 - 0
cyber_agent/docs/application-framework-m1.md

@@ -0,0 +1,192 @@
+# M1 应用框架设计基线
+
+> **受众**:框架团队内部
+>
+> **状态**:M1 已批准设计基线;`[CURRENT]` 表示当前代码事实,`[M2 TARGET]` / `[M3 TARGET]` 表示尚未实现的后续目标
+>
+> **代码基线**:`dev_lsh@98713f26`(2026-07-17)
+
+## 1. 目标与边界
+
+M1 解决的不是“马上发布一套新 SDK”,而是先回答三个问题:
+
+1. 当前框架已经可靠地提供什么,真实缺什么。
+2. 框架与业务应用分别拥有哪些状态和责任。
+3. M2、M3 应在现有 Runner、Trace 和 Recursive 协议上增加什么,而不是重新实现什么。
+
+最终目标是让业务团队只实现业务目标、资料、角色、工具、候选存储和质量规则,不修改 `AgentRunner`、Recursive 协议、TraceStore、Validator 或恢复机制。
+
+M1 本身只交付文档和决策,不新增 Python 类型、运行时分支或公共导出。面向业务团队的接口仍是草案,见 [Application API 0.1 草案](./application-api-0.1-draft.md)。
+
+本阶段明确不做:
+
+- 脚本段落、账号人设、Pattern、脚本元素或 SQL branch 等业务模型。
+- 第二个 Agent Loop、Workflow DSL 或同步 EventBus。
+- 多租户、分布式运行、多 Worker 写入或远程 Recursive Agent。
+- 在真实应用验证前冻结公共 API。
+
+## 2. 当前能力就绪矩阵
+
+状态含义:
+
+- **已有**:核心语义、持久化和关键门禁均已实现,并有专项测试。
+- **部分**:存在可复用实现,但尚未形成应用级装配合同,或缺少隔离/公共入口/专项测试。
+- **缺失**:没有可作为该能力权威来源的实现。
+
+| 状态 | 能力 | 权威代码证据 | 自动化测试证据 | 当前持久化与限制 | 责任与后续 |
+|---|---|---|---|---|---|
+| 已有 | Trace 生命周期与恢复 | [`Trace`](../trace/models.py)、[`AgentRunner._prepare_new_trace/_prepare_existing_trace`](../core/runner.py)、[`RunConfigSnapshotV1`](../core/run_snapshot.py) | [`test_runtime_hardening.py`](../../tests/test_runtime_hardening.py)、[`test_agent_mode.py`](../../tests/test_agent_mode.py) | Trace meta、消息和带 hash 的运行快照落盘;Recursive 旧 Trace 无快照时拒绝不可靠恢复 | 框架权威;M3 将应用身份加入同一恢复合同 |
+| 已有 | Recursive 任务树 | [`AgentPolicy`](../core/agent_mode.py)、[`GoalTree`](../trace/goal_models.py)、[`agent` 调度](../tools/builtin/subagent.py) | [`test_recursive_child_scheduling.py`](../../tests/test_recursive_child_scheduling.py)、[`test_recursive_subtree_cancellation.py`](../../tests/test_recursive_subtree_cancellation.py) | 深度、每父孩子数、并发和父子 Trace 关系固化;Recursive revision 2 禁止 remote | 框架权威;应用只决定业务任务内容 |
+| 已有 | TaskBrief / TaskReport / TaskReview | [`task_protocol.py`](../core/task_protocol.py)、[`task_protocol` 工具](../tools/builtin/task_protocol.py) | [`test_task_protocol.py`](../../tests/test_task_protocol.py)、[`test_recursive_replan_context.py`](../../tests/test_recursive_replan_context.py) | `Trace.context.task_protocol` 保存 Brief 版本、报告、审核、action 和 replan;Goal 只是投影 | 框架权威;M2 在同一协议状态中补 TaskProgress |
+| 缺失 | Task 内部推进状态 | 当前只有 Brief、最终 Report 和父级 Review;`new_task_protocol()` 没有中间推进模型 | 无 | 没有可版本化的 blocker、question、finding、hypothesis、work item 或 candidate 状态 | `[M2 TARGET]` 框架提供 TaskProgress 和结构化命令;应用填写业务内容 |
+| 已有 | Context 授权与逐边转授 | [`ContextSnapshot/ContextRef` 策略](../core/context_policy.py)、[`read_context_ref`](../tools/builtin/context.py) | [`test_recursive_context_policy.py`](../../tests/test_recursive_context_policy.py)、[`test_recursive_context_integration.py`](../../tests/test_recursive_context_integration.py) | 内容寻址快照绑定 root、uid、来源和版本;只允许父级已授权引用继续转授 | 框架执行授权;应用级资料枚举 Provider 仍缺失 |
+| 部分 | 业务资料装配 | `TaskBrief.context/context_refs` 和 ContextSnapshot 可承载资料,但资料仍由调用方手工组装 | 同上,只覆盖授权和限额,不覆盖 Provider 合同 | 没有来源目录、优先级、继承声明或应用版本入口 | `[M3 TARGET]` 应用实现 `TaskContextProvider`,框架做授权、去重、裁剪和预算 |
+| 部分 | Agent 角色 | [`AgentPreset/AGENT_PRESETS`](../core/presets.py)、[`AgentRunner._build_system_prompt`](../core/runner.py) | 无独立角色目录/隔离测试 | Preset 是进程全局可变字典;同名角色会跨应用污染;无应用归属和配置 hash | `[M3 TARGET]` 应用声明 `AgentRole`,内部 Runtime 解析并固化角色快照 |
+| 已有 | 工具白名单与执行门禁 | [`ToolRegistry`](../tools/registry.py)、Recursive capability 交集和 Runner 的 runtime tool 计算 | [`test_recursive_tool_capabilities.py`](../../tests/test_recursive_tool_capabilities.py)、[`test_runtime_hardening.py`](../../tests/test_runtime_hardening.py) | 模型 Schema 与 dispatch 使用同一 allowlist;URL policy 和参数 hash 在执行前复核 | 框架权威;M3 的 `ToolSet` 只负责应用级声明,不新建执行器 |
+| 已有 | 人工确认 | [`ToolApprovalBatchV1`](../tools/approval.py)、Runner 审批状态机和 Trace Run API | [`test_runtime_hardening.py`](../../tests/test_runtime_hardening.py)、[`test_local_api_boundary.py`](../../tests/test_local_api_boundary.py) | `tool_approvals.json` 持久化批次;整批等待;执行中崩溃标记 unknown,不自动重试 | 框架权威;应用只声明工具是否需确认及可编辑字段 |
+| 已有 | Artifact 引用与可信解析 | [`ArtifactRef/ArtifactResolver`](../core/artifacts.py)、Validator 材料解析 | [`test_recursive_validation_artifacts.py`](../../tests/test_recursive_validation_artifacts.py) | 引用包含 version/hash/kind;Resolver 校验 root 和 uid;框架不读取任意业务路径 | 框架保管引用和校验;应用实现 Resolver 与真实存储 |
+| 部分 | Artifact 应用接入 | `AgentRunner` 构造函数可注入单个 `artifact_resolver` | Artifact 解析有测试,但没有应用注册或多应用隔离测试 | Resolver 与某个 Runner 实例绑定,无法由持久化应用身份恢复 | `[M3 TARGET]` 通过 ApplicationBinding 注入,继续复用现有 `ArtifactResolver` 名称 |
+| 缺失 | 候选生命周期 | `ArtifactRef` 能引用产物,但没有 candidate 身份、血缘、采用、暂存或放弃语义 | 无 | 无候选权威状态或审计事件 | `[M3 TARGET]` 框架定义 `CandidateRef` 与生命周期;应用实现 `CandidateRepository` 的内容、fork/merge 和写回 |
+| 已有 | 分层 Validator | [`ValidationPolicy/Plan/Result`](../core/validation.py)、Runner Validator 生命周期 | [`test_recursive_validation_core.py`](../../tests/test_recursive_validation_core.py)、[`test_recursive_validator_lifecycle_complex.py`](../../tests/test_recursive_validator_lifecycle_complex.py)、[`test_recursive_validator_web.py`](../../tests/test_recursive_validator_web.py) | Policy、settings、plan hash 和 Scope checkpoint 固化;结果必须覆盖计划内全部 check_id | 框架权威调度和聚合;父级通过 TaskReview 决定去向 |
+| 部分 | 确定性业务质量规则 | 编译器只对材料硬错误产生确定性检查;业务 completion criteria 仍是 LLM 检查 | Validator 测试覆盖当前计划完整性,不存在业务规则 Provider 测试 | 无可注册的业务确定性执行器、版本或输入声明 | `[M3 TARGET]` 应用实现 `QualityCheckProvider`;框架编译、固化版本并执行 |
+| 部分 | Trace 事件 | [`TraceStore.append_event/get_events`](../trace/protocols.py)、[`events.jsonl`](../trace/store.py)、WebSocket 重放 | [`test_runtime_hardening.py`](../../tests/test_runtime_hardening.py)、[`test_local_api_boundary.py`](../../tests/test_local_api_boundary.py) | 事件有单 Trace 单调 event_id,但 event type/payload 仍是开放字典;没有应用投影 cursor | `[M3 TARGET]` 规范业务可消费事件并提供幂等 `RunEventProjector`;不引入 EventBus |
+| 已有 | Recursive 树级预算 | [`ResourceBudget/ResourceBudgetController`](../core/resource_budget.py) | [`test_recursive_resource_budget.py`](../../tests/test_recursive_resource_budget.py) | 根 Trace 固化预算和累计用量;停止、回溯不退还已消耗资源 | 框架权威;M3 用 `RunLimits` 形成应用声明和框架硬上限的交集 |
+| 部分 | Memory / Knowledge | [`MemoryConfig`](../core/memory.py)、[`DreamScope`](../core/dream.py)、[`KnowledgeConfig`](../tools/builtin/knowledge.py) | [`test_dream_security.py`](../../tests/test_dream_security.py)、Recursive runtime tests | Memory 以 uid/agent_type/memory_identity 隔离;Knowledge 仍通过 RunConfig/工具配置 | 框架可选能力;M3 只允许应用选择配置,不把业务数据库伪装成 Memory |
+| 缺失 | 应用注册与恢复 | RunConfig 快照只有 `project_name`,Runner 直接持有 policy/resolver/registry 等依赖 | 只有 project runner 与快照恢复测试 | 无 `application_id/version/config_hash`,无法从 Trace 确定性恢复应用装配 | `[M3 TARGET]` 内部 `ApplicationRegistry/ApplicationBinding/ApplicationRuntime` |
+| 缺失 | 应用接入合规测试 | 当前测试直接构造 Runner、Trace 或内置模型 | 无 | 没有业务实现必须通过的黑盒合同套件 | `[M3 TARGET]` 先建立内部 contract tests;后续 M8 打包成业务接入套件 |
+
+## 3. 状态权威
+
+Recursive 任务存在多种“状态”,但每种状态只能回答一个问题。
+
+| 对象 | 唯一回答的问题 | 权威写入者 | 禁止承担的职责 |
+|---|---|---|---|
+| `Trace.status` | 这次执行现在是否运行、等待确认、完成、失败或停止? | Runner / Run API | 不表示业务 Task 是否被父级接受 |
+| `Goal.status` | 当前 UI 和调度投影显示在哪个任务位置? | 框架从协议动作投影 | 不作为 Recursive 协议真相,不自行级联父级或切换兄弟 |
+| `RootTaskAnchor` | 整棵任务树最终要达成什么、有哪些根约束? | 根 Run 创建者,框架固化 | 子 Agent 不得改写或重新概括 |
+| `TaskBrief` | 当前 Task 被委派了什么、为何产生、交付和验收要求是什么? | 直接父级提出,框架规范化和版本化 | 不记录执行中的变化 |
+| `TaskProgress` `[M2 TARGET]` | 当前 Task 卡在哪里、确认了什么、准备尝试什么、有哪些候选? | 当前 Task 通过框架命令更新 | 不拥有 completed/passed/failed 终态,不复制其他权威结果 |
+| `TaskReport` | 子 Agent 正式提交了什么结果和未解决问题? | 子 Agent 提交,框架注入 trace identity | 执行者自检不能替代 Validator |
+| `ValidationResult` | 权威材料是否满足本次 ValidationPlan?失败应从哪一层重试? | Validator | 不直接修改 TaskProgress,不决定父级最终动作 |
+| `TaskReview` | 父级接受、修订、再拆分、重规划、上行还是失败? | 直接父级,框架按决策矩阵校验 | 不伪造或覆盖 Validator 的 `retry_from` |
+| `RunConfigSnapshot` | 这个 Run 应按哪套行为配置恢复? | 框架在新 Run 创建时固化 | 续跑请求不得覆盖行为字段 |
+
+### 3.1 TaskProgress 的约束输入
+
+M2 实现时必须遵守:
+
+- 字段使用 `phase`,不使用含糊的 `status`。
+- 通过 `task_brief_version` 引用当前 TaskBrief,不复制 `target/objective`。
+- 通过结果引用关联 ValidationResult 和 TaskReview,不复制 `review_result/next_action`。
+- 版本与 `effective_at_sequence`、消息 head 和回溯分支绑定;回溯产生新版本,不改写旧历史。
+- Agent、工具、Validator 和父级只能通过各自获授权的命令写入,业务代码不得直接修改 `Trace.context.task_protocol`。
+- 只保存问题、证据引用、Finding、方案、候选和简短 decision rationale;不保存模型原始思维链或隐藏推理文本。
+
+## 4. 框架与应用责任边界
+
+| 领域 | 框架负责 | 应用负责 |
+|---|---|---|
+| 任务 | Task identity、父子关系、协议状态转换、版本和权限 | 业务目标、拆分理由、交付内容和验收标准 |
+| Context | 引用授权、逐边转授、hash、去重、裁剪和 Token 预算 | 枚举可用业务资料,提供来源、版本、优先级和继承建议 |
+| 角色 | 解析、校验、隔离、固化角色配置,执行模型与资源门禁 | Prompt、Skill、业务角色定义和可创建的子角色关系 |
+| 工具 | Schema、allowlist、URL policy、确认、执行、结果和审计 | 工具实现、副作用声明、幂等性和业务输入输出 schema |
+| Artifact | `ArtifactRef`、hash/归属校验和 Validator 安全读取 | 内容存储、ACL、上传、索引和 Resolver 实现 |
+| Candidate | identity、Run/Task 归属、血缘、生命周期和审计 | 内容、fork、merge、冲突处理、采用后的业务写回 |
+| Quality | 计划编译、规则版本固化、调度、结果完整性和聚合 | 业务确定性规则、rubric 和规则所需业务材料 |
+| Event | 规范事件 envelope、顺序、重放和投影 checkpoint | 业务 DB/UI/通知/分析的幂等投影 |
+| Run | 停止、恢复、回溯、配置快照、预算和错误语义 | 输入、最终输出解释和应用级默认限制 |
+
+判断标准:替换为广告创作、游戏剧情或研究报告仍成立的是框架机制;只对脚本构建成立的是应用实现。
+
+## 5. 内部 Application Runtime 目标形态
+
+`ApplicationRuntime` 是现有 Runner 前的装配层,不是新的执行引擎:
+
+```text
+业务入口
+  → ApplicationRegistry 按 application_id + version 解析 AgentApplication
+  → ApplicationBinding 校验并计算 config_hash
+  → ApplicationRuntime 把角色、工具、Provider、规则和限制编译为现有依赖
+  → AgentRunner 执行现有 Agent Loop
+  → TraceStore 保存权威状态和事件
+  → RunEventProjector 异步、幂等地投影业务视图
+```
+
+装配层必须遵守:
+
+- `AgentApplication` 是不可变声明;Provider 是有行为的 Protocol 端口。
+- `ApplicationBinding` 是本次 Run 解析后的内部快照,不允许业务代码在运行中替换。
+- 新 Run 将 `application_id/application_version/config_hash`、角色 hash 和解析后的行为配置写入恢复快照。
+- 续跑只解析相同应用版本;缺失或 hash 不一致时失败关闭。
+- Provider 凭证、连接池、客户端对象和其他不可序列化运行时依赖不进入 config hash。
+- ToolSet 编译进现有 ToolRegistry 权限计算;Artifact 继续使用现有 ArtifactResolver。
+- 应用事件基于现有 append-only Trace events 投影;本设计不恢复历史 Decision 4 所反对的同步 EventBus。
+
+## 6. 统一术语
+
+| 名称 | 层级 | 决策 |
+|---|---|---|
+| `ApplicationRef` | 公共草案 | 应用 ID、版本和配置 hash 的不可变引用 |
+| `AgentApplication` | 公共草案 | 应用声明,不是 Runner |
+| `AgentRole` | 公共草案 | 应用命名空间内的角色配置 |
+| `TaskProgress` | 框架模型目标 | M2 的任务推进状态,业务只读视图、命令式更新 |
+| `TaskContextProvider` | 应用端口 | 枚举业务资料,框架执行授权策略 |
+| `ToolSet` | 应用声明 | 编译进现有 ToolRegistry,不形成第二注册表 |
+| `ArtifactResolver` | 已有应用端口 | 保留现名,不新增 `ArtifactReader` |
+| `CandidateRef` | 框架模型目标 | 不可变候选身份、归属和血缘 |
+| `CandidateRepository` | 应用端口 | 替代 `CandidateStore`,强调内容存储由应用实现 |
+| `QualityCheckProvider` | 应用端口 | 提供版本化的确定性业务规则 |
+| `RunEventProjector` | 应用端口 | 按 cursor 幂等投影,替代含糊的同步 Handler |
+| `RunLimits` | 公共草案 | 应用声明限制,与框架硬上限取更严格值 |
+| `ApplicationRegistry` / `ApplicationBinding` / `ApplicationRuntime` | 框架内部 | M3 装配层,不进入首版公共 API |
+
+公共类名不带 `V1`;所有需要落盘、跨进程或恢复的结构和事件必须带 `schema_version`。Application API 在 M6 发布前均标记为 `0.1 Draft`,不承诺兼容。
+
+## 7. 后续工程输入
+
+### M2:TaskProgress
+
+- 在现有 `task_protocol` 权威状态内增加 sequence-bound、revisioned 的 TaskProgress。
+- 定义 `phase`、问题、Finding、方案、WorkItem、CandidateRef 和提交准备度。
+- 提供结构化命令和写入权限,不允许直接修改 context。
+- 接入停止、续跑、回溯、Context 注入和 Validator 输入。
+- 保持 ValidationResult 与 TaskReview 为独立权威结果。
+
+### M3A:Application Runtime 主干
+
+- 建立应用身份、Registry、Binding 和 Runtime 装配。
+- 实现应用命名空间内的 AgentRole、ToolSet、TaskContextProvider、QualityCheckProvider 和 RunLimits。
+- 将应用身份和角色 hash 加入严格恢复快照。
+- 建立应用 A/B 隔离和恢复 contract tests。
+
+### M3B:候选和事件投影
+
+- 建立 CandidateRef 生命周期、权限和审计事件。
+- 定义 CandidateRepository 端口,fork/merge 保留为业务语义。
+- 稳定业务可消费的事件 envelope 和 RunEventProjector cursor。
+- 投影失败不得破坏 Trace;支持重放和幂等恢复。
+
+### M4—M5:组装与参考应用
+
+- 先用 [reference example 合同](./application-reference-contract.md) 做 walking skeleton。
+- 再完成包含停止、重启、回溯、局部失败和候选采用的完整业务链路。
+- 只有真实应用不改内核即可运行后,才进入 Application API 0.1 的实现与冻结。
+
+## 8. 外部实践如何转化为本项目决策
+
+- [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) 和 [Anthropic Building Effective Agents](https://www.anthropic.com/engineering/building-effective-agents) 都强调少量、可组合原语;因此不新增第二个 Runner 或通用 Workflow DSL。
+- [Google ADK App pattern](https://github.com/google/adk-python/blob/main/AGENTS.md) 用 App 组合 root agent、plugins 和服务;本项目采用应用声明 + Provider 端口,但保留现有 AgentRunner 为唯一执行引擎。
+- [LangGraph Persistence](https://docs.langchain.com/oss/python/langgraph/persistence) 将状态变化保存为新 checkpoint;本项目沿用 message sequence/head 和协议 revision,不原地覆盖回溯历史。
+- [Microsoft Agent Framework Checkpoints](https://learn.microsoft.com/en-us/agent-framework/workflows/checkpoints) 将存储做成可替换协议;本项目继续以 TraceStore 为边界,本轮不引入数据库。
+- [OpenAI HITL RunState](https://openai.github.io/openai-agents-python/human_in_the_loop/) 要求长期等待任务绑定定义版本;本项目将应用版本和 config hash 纳入恢复合同。
+
+## 9. M1 完成标准
+
+M1 完成时,框架团队必须能从本文逐项回答:
+
+- 当前能力是真有、部分有还是没有,证据在哪里。
+- 某个状态冲突时以哪个对象为准,谁有写入权限。
+- 业务团队要实现哪些 Provider,哪些内核绝对不应修改。
+- M2、M3 的实现边界和 reference example 验收依赖是什么。
+
+本文不构成可导入 API。业务接入视角和草案接口见 [Application API 0.1 草案](./application-api-0.1-draft.md),后续示例的业务验收见 [reference example 合同](./application-reference-contract.md)。

+ 89 - 0
cyber_agent/docs/decisions.md

@@ -1371,3 +1371,92 @@ context = {
 **实现**:`cyber_agent/tools/builtin/subagent.py`(路由)、`knowhub/server.py::agent_api`(`/api/agent`)、`knowhub/agents/librarian.py` / `research.py`(去 trace_map)。文档:`cyber_agent/docs/tools.md § Agent 工具`、`knowhub/docs/remote-agents.md`、`knowhub/docs/api.md`。
 
 ---
+
+## Decision 26: 应用框架边界、状态权威与版本化装配
+
+**日期**:2026-07-17
+
+**状态**:M1 设计基线;本决策定义 M2/M3 的实现约束,不表示 Application API 已实现。
+
+### 背景
+
+M0 完成了本地 Trace API、运行恢复、工具确认、文件账本、SideBranch、Validator、Dream 和 Recursive 协议的安全加固。下一阶段要让业务团队在不修改 Runner、TraceStore、Recursive 协议和 Validator 的前提下构建应用。
+
+当前应用能力分散在 `RunConfig`、进程全局 `AGENT_PRESETS`、`ToolRegistry`、`ContextPolicy`、`ArtifactResolver` 和 `ValidationPolicy`。如果直接发布 SDK,会重复实现现有能力,也会让 Trace、Goal、任务进度、验收和父级审核形成多套相互覆盖的状态。
+
+详细代码证据和能力矩阵见 [`application-framework-m1.md`](./application-framework-m1.md)。
+
+### 决策
+
+#### 26a. 保留一个 Agent Runner
+
+- `AgentRunner` 继续是唯一 Agent Loop。
+- M3 的 `ApplicationRuntime` 只是装配层:解析应用、校验配置、构建现有 Runner 依赖并固化恢复快照。
+- 不引入第二个 Runner、Workflow DSL 或新的工具执行器。
+- `ToolSet` 必须编译进现有 ToolRegistry 权限计算;Artifact 继续使用现有 `ArtifactResolver`。
+
+#### 26b. 每种状态只有一个权威来源
+
+| 对象 | 权威职责 |
+|---|---|
+| `Trace.status` | 执行生命周期 |
+| `Goal.status` | UI 和调度投影,不是 Recursive 协议真相 |
+| `RootTaskAnchor` | 不可变根目标和根约束 |
+| `TaskBrief` | 版本化任务合同 |
+| `TaskProgress`(M2) | 执行中的结构化推进状态,不拥有验收终态 |
+| `TaskReport` | 子 Agent 正式提交 |
+| `ValidationResult` | Validator 权威验收结论 |
+| `TaskReview` | 直接父级的权威下一步决定 |
+| `RunConfigSnapshot` | 恢复时的行为配置 |
+
+因此:
+
+- M2 使用 `TaskProgress.phase`,不增加另一个含糊的 `status`。
+- TaskProgress 通过 revision/ref 关联 TaskBrief、ValidationResult 和 TaskReview,不复制 `target/review_result/next_action`。
+- Validator 只产生 ValidationResult,不直接修改 TaskProgress。
+- Goal 只能由协议动作投影,Recursive 不恢复自动 sibling 切换或父级级联完成。
+- 应用和模型都不得直接写 `Trace.context.task_protocol`,必须走框架命令。
+- TaskProgress 只记录结构化事实、引用和简短判断依据,不保存模型原始思维链。
+
+#### 26c. 框架提供机制,应用提供业务语义
+
+框架负责身份、父子关系、状态转换、Context 授权、工具门禁、Artifact 校验、Validator 调度、持久化恢复、规范事件和资源限制。
+
+应用负责业务目标、角色 Prompt/Skill、资料枚举、工具实现、候选内容和合并、业务质量规则、业务投影和最终输出。
+
+框架中禁止出现脚本段落、账号人设、Pattern、脚本元素、SQL branch 等只对脚本构建成立的概念。
+
+#### 26d. 应用装配必须可精确恢复
+
+- `AgentApplication` 是不可变应用声明;有行为的外部能力使用 Provider Protocol。
+- 新 Run 必须固化 `application_id/application_version/config_hash`、角色 hash 和解析后的行为配置。
+- 续跑只解析同一应用版本和 config hash;缺失或不一致时失败关闭,不使用当前默认配置兜底。
+- Provider 凭证、连接池、客户端和其他运行时对象不进入 config hash。
+- 公共类名不带 `V1`;所有落盘、恢复或跨进程结构必须包含 `schema_version`。
+
+#### 26e. 事件使用 Trace 日志投影,不引入 EventBus
+
+历史 Decision 4 的“无同步 EventBus”原则继续成立,但“系统没有事件”已经不符合当前代码:TraceStore 现在维护 append-only `events.jsonl` 和单调 event_id。
+
+本决策对 Decision 4 的事件现状描述作出替代:M3 在现有 Trace 事件上定义稳定 envelope 和幂等 `RunEventProjector`。投影失败不能回滚或破坏权威 Trace,恢复时按 cursor 重放。
+
+#### 26f. 统一接口命名
+
+- 保留现有 `ArtifactResolver`,不新增同义 `ArtifactReader`。
+- 框架定义 `CandidateRef` 的身份、归属、血缘和生命周期;应用实现 `CandidateRepository` 的内容、fork、merge、冲突和写回。弃用含义不清的 `CandidateStore` 草案名称。
+- 使用 `RunEventProjector` 表达异步、可重放投影,不使用暗示同步副作用的 `RunEventHandler`。
+- `ApplicationRegistry`、`ApplicationBinding`、`ApplicationRuntime` 是框架内部组件,不进入首版业务 API。
+
+### 后果
+
+- M1 只发布内部基线、业务接口草案和 reference example 合同,不新增运行时代码。
+- M2 先实现 TaskProgress;M3A 实现应用装配主干;M3B 实现候选生命周期和事件投影。
+- Application API 0.1 在真实 reference example 证明业务无需修改内核前,不作兼容承诺。
+
+**实现约束文档**:[`application-framework-m1.md`](./application-framework-m1.md)
+
+**业务接口草案**:[`application-api-0.1-draft.md`](./application-api-0.1-draft.md)
+
+**后续示例合同**:[`application-reference-contract.md`](./application-reference-contract.md)
+
+---