Files
nana-story/docs/status/2026-07-28-m1-wave1.md
T

3.7 KiB
Raw Blame History

M1/M2 第一并行波次状态

日期:2026-07-28
集成分支:integration/v1
契约基线:3dacc92

本波次目标

在不修改公共领域契约的前提下,同时推进:

  • Core:确定性状态 reducer
  • Runtime:Turn 边界与确定性世界书选择;
  • Experience:基于同一 PlayerView 的可交互假数据体验;
  • Integrator:分支追加、恢复与回溯语义的存储接口。

游戏运行时仍为单模型。本波次使用 FakeProvider 和浏览器本地 adapter, 不引入导演 Agent 或其他运行时子智能体。

已集成

State Engine

  • apply_delta 是状态变化的唯一纯函数入口。
  • 整个 delta 先作用于克隆状态,任一操作失败则不提交部分结果。
  • 支持全部当前 StateOp
  • 六维关系使用有向键 from->to,数值范围为 0..100
  • 单个关系操作限制为 ±8
  • 许诺 ID 唯一并执行生命周期约束。
  • 知识、物品和判定记录 ID 唯一。
  • 物品转移验证当前 holder,保留 owner。
  • 判定按 action_id 复用:完全相同的记录幂等,冲突记录拒绝。
  • 时钟推进不会超过上限。

Store Seam

  • InMemoryStoryStore 提供无数据库的确定性集成测试实现。
  • 节点与物化状态的 story、branch 和 current node 必须一致。
  • 同一分支只允许追加到当前 head。
  • 新分支可以从同一故事的旧节点创建。
  • 创建新分支不会移动原分支 head。
  • 所有校验先于写入,失败不会留下部分节点或状态。

这不是 SQLite 的替代品。后续 SQLite 实现必须保持同一追加与分支语义。

Runtime Seam

  • TurnRequest 在调用 provider 前验证。
  • speak_or_act 拒绝空白输入;continue 允许空输入。
  • provider 返回后校验 story、branch、committed node 与 PlayerView 一致。
  • provider 错误映射为稳定、脱敏的 TurnFailure
  • FakeProvider 按 FIFO 返回录制结果。
  • 世界书通过 required flags、tags 和 keywords 确定性选择。
  • 选择结果保持输入顺序、按 ID 去重并限制最多 8 条。

Experience

  • 自由输入和“继续”经过同一 TurnRequest → TurnResult 边界。
  • 点击行动建议只填入输入框,不自动提交。
  • 提交期间清空输入并显示忙碌状态。
  • 最近的短演出节拍连续显示。
  • 持有物/线索/许诺、模糊六维关系、故事回溯为互斥面板。
  • 所有面板只读取 PlayerView
  • 回溯入口明确标记为尚未持久化,不伪装成已创建分支。
  • Escape、ARIA 和键盘焦点具备基础支持。

已通过验证

node scripts/verify-contracts.mjs
  15 schemas and TypeScript DTO source hash verified

vue-tsc --noEmit

vitest run
  3 test files passed
  11 tests passed

vite build

Web 侧仍未发现契约漂移,生产构建成功。

尚未通过

当前 Work 环境仍没有 cargorustcrustfmt。因此本波次新增的 Rust reducer、runtime 和 store 测试尚未实际编译或执行,M0 的 Rust/Tauri 门也仍然未关闭。

必须在 Rust 1.96 环境执行:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo run -p nana-contracts -- --check
pnpm tauri dev

在这些命令通过前,不把 M0 或 M1 标记为完成。

下一波次

  1. 在 Rust 1.96 环境修正首次编译、格式和 Clippy 问题。
  2. RuntimeState 增加脱敏 PlayerView 投影实现和泄密测试。
  3. 在同一 StoryStore 语义下实现 SQLite 事务、节点与检查点。
  4. 将浏览器本地 Turn adapter 替换为 Tauri submit_turn 命令。
  5. 用“天亮前一定回来”fixture 串起许诺、希望变化、保存、恢复和回溯分叉。