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

110 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M1/M2 第三并行波次状态
日期:2026-07-28
集成分支:`integration/v1`
起始基线:`4157f87`
## 本波次目标
- 在 Rust 1.96 下关闭此前未执行的核心编译、测试与 Clippy 门;
- 将动态演出完整保存到故事节点,并从节点恢复同一 `PlayerView`
- 为 SQLite 建立可辨认、可拒绝损坏状态的 schema 生命周期;
- 实现真实 `lapp-rs` 非流式 TurnPlan provider
- 保持模型、状态提交和玩家视图之间的安全边界。
开发继续使用 1 个集成人和 3 个独立 worktree。三个工作面分别负责
Presentation、Store Hardening 和 LAPP Provider;游戏运行时仍是单模型架构。
## 已集成
### 可恢复的演出快照
`StoryNode` 现在持久化一份 `PresentationSnapshot`
- scene id 与公开标题;
- 主角色 id、名称、最终 expression 与 pose
- 本轮演出 beats
- 可编辑行动 suggestions
- `canContinue`
`TurnPlan` 只提交内部演出快照和 `StateDelta`,最终 `PlayerView` 仍由可信投影器
在事务提交后生成。旧的 beats-only 节点可通过默认值反序列化;重启恢复会保留
表情、姿态、节拍和建议,不再依赖运行时重新生成。
前端已消费 `characterExpression``characterPose`,浏览器确定性 adapter 也会
按本轮最后一个视觉指令更新角色状态。
### SQLite schema 生命周期
- 新数据库初始化为 schema v1,并通过 `PRAGMA user_version` 标记。
- 完整的旧版无版本数据库会在事务内采用为 v1,不丢失节点、状态或分支头。
- 不完整的 v0、损坏的 v1 和未来版本都会被拒绝,不会静默重建。
- 文件数据库启用 WAL、5 秒 busy timeout、foreign keys 与 synchronous NORMAL。
- 写入、恢复、结构列和 `state_hash` 的交叉校验继续保留。
### LAPP TurnPlan provider
- 使用固定的相邻 `lapp-rs`,启用 Rustls 客户端与系统凭据库。
- 非流式 chat 在独立 Tokio worker 中运行。
- 接受一个指定工具调用或裸 JSON,两者都经过相同严格结构校验。
- 模型只能返回 scene、character、beats、delta、suggestions 与 canContinue。
- `PlayerView``committedNodeId`、未知字段、歧义工具调用和无效标识符都会被拒绝。
- 提交节点 ID 由 story、branch 与 action 的稳定哈希产生,不能由模型伪造。
- 上游错误与无效输出经过脱敏,不回显 provider 原文或凭据。
真实 provider 暂不作为 Tauri 默认实现。下一步必须先建立上下文编译器和由引擎
掌控的类型化隐藏检定工具循环,避免模型直接提出未经裁决的判定记录或跨过
“一轮只提交一次”的原子边界。
### 桌面接线
- Tauri 从已提交节点恢复完整演出快照。
- “许诺 → 提交 → 恢复”测试增加 beats、suggestions、expression 与 pose 一致性。
- 补齐应用 SVG 源图标和 512×512 RGBA PNGTauri 宏可完整展开。
- `Cargo.lock` 首次纳入版本控制,固定 Rust 依赖解析结果。
## 已通过验证
```text
Rust 1.96.0
cargo fmt --all -- --check
cargo test -p nana-domain -p nana-engine -p nana-runtime -p nana-store -p nana-contracts
67 tests passed
cargo clippy -p nana-domain -p nana-engine -p nana-runtime -p nana-store \
-p nana-contracts --all-targets -- -D warnings
cargo check -p nana-story-app --all-targets
cargo clippy -p nana-story-app --all-targets -- -D warnings
Tauri lib、binary 与 6 个 test target 类型检查通过
node scripts/verify-contracts.mjs
16 schemas and TypeScript DTO source hash verified
vue-tsc --noEmit
vitest run
4 test files passed
12 tests passed
vite build
production build succeeded
```
当前 Linux Work 环境没有 WebKitGTK、Rsvg 与完整桌面链接依赖。Tauri 检查使用
本地 compile-only pkg-config shim 完成 Rust、宏和测试 target 的类型检查,
不等价于实际链接或窗口启动。真实 `pnpm tauri dev` 和 Windows 打包仍需在具备
原生依赖的环境验证。
## 下一波次
1. 建立确定性的上下文编译器,按预算选择角色卡、世界书、Persona、剧情与状态。
2. 建立类型化工具循环,由引擎执行隐藏 CoC7 判定和受控状态操作。
3. 将 LAPP provider 接入该工具循环,并保持整轮只有一次 SQLite 提交。
4. 为回溯面板接入“从这里继续”,创建新分支且保留旧分支头。
5. 在 Windows CI 或本机完成 Tauri 启动、重启恢复和安装包冒烟。