# M2 第七波:当前分支上下文检查点 日期:2026-07-29 ## 本轮结果 本轮完成了长分支上下文主链:运行时按实际 LAPP 模型预算编排 prompt schema v3; 超出预算时使用当前选中的同一个模型生成玩家安全的滚动摘要;摘要与来源指纹组成 非权威检查点,并在最终回合成功时与新故事节点原子提交。历史不会为了适配窗口而被 静默截断。 这套机制适用于普通继续与重生成。它不引入导演 Agent、独立摘要模型、向量记忆库或 跨分支记忆。 ## SQLite schema v3 - 新增 `context_checkpoints` 缓存表,以不可变的故事节点作为 host,保存覆盖范围、 prompt / checkpoint schema 版本、稳定前缀哈希、摘要和叙事来源哈希。 - schema v1 与 v2 数据库都能迁移至 v3;迁移不会修改故事节点、线路头、物化状态或 活动线路。 - Memory 与 SQLite Store 使用同一检查点语义:只沿目标节点的 `parent_id` 祖先链 查找最近的可达检查点,兄弟分支和其他故事不可见。 - 缓存行的类型、版本、大小、规范 SHA-256、host 和覆盖范围都会被校验。损坏或未知 版本的行被当作可重建的 cache miss,并继续查找更早的有效祖先;权威祖先链损坏仍是 硬错误。 - 删除全部检查点不会改变节点、线路、状态哈希或 `PlayerView`。 - 内存和 SQLite 后端均覆盖 500 节点祖先链读取与检查点查找,长线路不再受界面层 200 节点展示限制。 ## 缓存友好的 prompt schema v3 模型输入固定分成三段: ```text stable_prefix branch_context checkpoint? raw_tail[] dynamic_tail ``` - `stable_prefix` 只包含角色、Persona、剧情模块、绑定世界书的版本来源及稳定安全 规则;资源未变化时保持字节一致,便于供应商前缀缓存命中。 - `branch_context` 使用一个已验证的祖先检查点加最近原文;至少保留最新的已提交节点, 节拍文本不会被截断。 - `dynamic_tail` 保留本轮输入、实际触发的世界书条目、剧情事件、可见状态与重生成的 固定定性结果,不允许被摘要替代。 - 输入预算来自当前 LAPP 模型的 `context_window` 和 `max_output_tokens`;缺失元数据 使用显式标记的保守回退。输出、system、工具 schema、消息 framing、一次隐藏检定 续调用与安全余量都会先从窗口中扣除。 - 完整请求在发给 provider 前再次预检。动态尾部、固定部分或单个历史节点本身无法 容纳时会失败关闭,而不是删字、截断或越过模型窗口。 - V1 每次玩家行动最多进行一次隐藏检定;这使为工具调用及其续写保留的预算存在明确 上界。初始请求会明确提示该限制,检定结果返回后以及重生成回合只向模型暴露 `submit_turn_plan`,不会再提供第二次检定工具。 - 可继续的候选节点会在 `begin_commit` 前,以提交后的状态、同一资源编译器和同一 模型预算验证一次最小“下一轮继续”上下文。即使回复满足静态字段上限,只要它作为 强制保留的最新原文会让下一轮无法编排,本轮就整体失败且不移动线路头。 ## 同模型滚动摘要 - 压缩复用当前 TurnPlan provider 的同一 LAPP executor、模型、调用闸门和 `TurnControl`,不会暗中切换模型或绕过供应商配置。 - 每次摘要请求都是新的单用途会话,只开放一个严格的 `submit_context_summary` 工具;正常文本、额外工具调用、未知字段、空白或超大摘要都会被拒绝。 - 首次加载超长分支时按有界块滚动摘要;后续压缩把上一个自包含摘要与新增的连续节点 一起压成新的自包含摘要,不在 prompt 中嵌套摘要链。 - 摘要来源仅包含当前根到覆盖节点路径上的实际玩家输入、公开场景、角色视觉状态和 已提交演出节拍。 - 精确关系值、骰点和难度、状态 delta、NPC 私物和私密知识、未触发世界书、未选择 建议、兄弟分支、凭据、原始供应商响应与推理过程都不进入摘要请求。 - 摘要分类由运行时固定为 `non_authoritative_narrative`;模型只能提供文本,摘要不能 作为规则触发、状态恢复或判定事实来源。 ## 原子提交与中断边界 - 压缩发生在模型生成正式 TurnPlan 之前。生成的检查点先停留在内存中,不会立即写库。 - 普通回合使用 `append_node_with_checkpoint`,重生成使用 `append_regenerated_node_with_checkpoint`;节点、物化状态、线路头与待提交检查点 在同一 Store 原子操作中落库。 - 检查点必须 host 在提交前的历史头上,并与该祖先链的覆盖范围一致。陈旧线路、 错误故事、无效范围或状态不一致都会使整次写入失败,节点与检查点均不落库。 - 取消或超时可发生在摘要、正式模型调用或最终提交边界之前。只要中断先于 `begin_commit`,待提交检查点与故事节点都会被丢弃,线路头保持不变。 - 一旦 `begin_commit` 成功,取消不再与写入竞争;调用方接收该原子提交的确定结果。 - 重生成继续复用原玩家行动、权威 delta、隐藏检定与终局状态;检查点只覆盖待替换 节点的父路径,旧节点及旧分支保持不可变。 ## 验证 - Rust workspace:**215** 项测试通过。 - Contracts:1。 - Domain:5。 - Engine:21。 - Runtime:106。 - Store:65。 - Tauri 后端:17。 - `cargo clippy --workspace --all-targets -- -D warnings`:通过。 - Web:5 个测试文件 / **29** 项测试、TypeScript 严格检查与生产构建通过。 - 契约:**25** 份 JSON Schema 与 TypeScript DTO 无漂移。 测试覆盖包括预算边界、prompt schema v3 编排、同模型严格摘要工具、滚动与增量摘要、 检查点哈希和失效、兄弟分支隔离、schema v1 / v2 迁移、缓存删除、500 节点祖先链、 节点与检查点原子提交、压缩后取消不移动线路头、隐藏检定工具单次暴露,以及合法但 会阻断后续上下文的超长回复在提交前被拒绝。 ## 尚未关闭 - 尚未使用用户实际 LAPP profile、Vault 凭据和在线模型完成端到端调用;本报告不宣称 在线 LAPP 冒烟通过。 - 本轮没有完成窗口截图或人工视觉检查;本报告不宣称视觉验收通过。 - Gitea SSH 推送在当前执行环境中仍未验证;本轮成果当前只能视为本地工作树状态, 不能宣称已经同步到远端。